//
//  HrdRcdViewCtrl.m
//  AccuroFit
//
//  Created by Yongfeng Li on 9/10/15.
//  Copyright (c) 2015 Nci Technology Inc. All rights reserved.
//

#import <AudioToolbox/AudioServices.h>
#import "AppDelegate.h"
#import "HrdRcdViewCtrl.h"
#import "UIOptionView.h"
#import "ViewController.h"

#import "H_Rate.h"
#import "H_RateRng.h"
#import "H_RateItem.h"
#import "UIView+Extension.h"
#define _FitHR_RngMin 0.65
#define _FitHR_RngMax 0.75
#define _BarHgtUpLimit 40
#define DefaultColor  [UIColor colorWithRed:0.44 green:0.18 blue:0.53 alpha:1.00];


#define LineH 1
#define LineA 0.7
static UIColor* _colBtnTitle;
static short _SynsSvrStep = 0;

//test
int _nCount = 0;
//test

@interface HrdRcdViewCtrl ()

@end

@implementation HrdRcdViewCtrl {
  UILabel* _lblMsg;
  UIImageView* _ivDropdwon;
    
  NIDropDownList* _ddlHrdList;
  UILabel* _lblDropDownList;
    
  //BOOL _bChoseBleDev;
    
  UILabel* _lblTotalTimeTip;
  UILabel* _lblTotalTimeVal;
  UIButton* _btnDelete;
    
  //UIButton* _btnStartStop;
  UICurveView* _pViewCurve;

    
  UILabel* _lblTotalPtTip;
  UILabel* _lblTotalPtVal;
    
  UILabel* _lblAvgPtMinTip;
  UILabel* _lblAvgPtMinVal;
    
  //Tpp view
  BOOL _bNoChooseDev;

  UICurveView* _pViewTpp;
    
  //bottom
  UIView*  _ivhLine;
  UIView*  _ivvLine1;
  UIView*  _ivvLine2;
    
  //bottom text
  UILabel* _lblAvgHrateTip;
  UILabel* _lblAvgHrateVal;
  UILabel* _lblAvgHrateUnit;
  
  UILabel* _lblMaxHrateTip;
  UILabel* _lblMaxHrateVal;
  UILabel* _lblMaxHrateUnit;
    
  UILabel* _lblCalBurnTip;
  UILabel* _lblCalBurnVal;
  
  UILabel* _lblZoneTip;
    
  //body info
  NSInteger _nBodyId;
  Byte _nAgeYear;
  float _fBodyWgt;
  short _nHgtMm;
  Byte _nSexNum;
  short _nExeLvl;
  
  //BLE comm
  BOOL _bIsSuptBLe;
  BOOL _bContBleDev;
  BOOL _bStartBleMeas;
    
  short _nLastHrate;
    
  NcitBleDevice* _ncitBleDev;
    
  //meas data
  NSInteger _nHrateId;
  int _nCountTick;
  NSTimer* _measTimer;
  
  double _dAvgHrate;
  short _nAvgHrate;
  short _nMaxHrate;
  short _nMinHrate;
  CGFloat _fBurnedVal;
    
  NSDate* _dtMeasStart;
  NSDate* _dtLast;
  NSDate* _dtMeas;
    
  //NSArray *_barColors;//for bar©
  CGFloat _afPointCoef[_nDurtBarNumber];
  CGFloat _faHrate[_nDurtBarNumber];
  CGFloat _faBarHgt[_nDurtBarNumber];
  CGFloat _faHrateMax;
    
  BOOL _bIpad;
  BOOL _bIp6p;
  BOOL _bIp6;
    
  NSMutableArray* _pHrtData;
  NSMutableArray* _pHrtRng;
  NSMutableArray* _pHrtItem;
  NSMutableArray* _pSyncItem;
    
  NSManagedObject* _pHrateItem;
  NSDate* _lastDatePos;
  
  //sync
  UIButton* _btnSyncTpp;
  UILabel* _lblSyncData;
  UIActivityIndicatorView* _actView;
  
  NSInteger _nSyncPos;
  NSInteger _nSyncTotalPack;
  NSInteger _nSyncCurrentPack;
  UIProgressView* _progView;
  
  NSURLSession* _netSession;
  //NSInteger _nLastSyncHrateId;
  NSMutableDictionary* _dicSyncHrate;
  
  BOOL _bSyncGetReqst;
  BOOL _bSyncGetNotNeed;
  BOOL _bMadeRcdMark;
  BOOL _bSyncSvrError;
  
  NSInteger _nCurSyncHrateId;
  NSString* _sIniSyncHrateId;
  NSString* _sNewSyncHrateId;
  BOOL _bUpdHrateId;
  BOOL _bSyncError;
  NSString* _sLastHrateId;
  
  UIImageView* _ivActType;
  NSInteger _nSelHrateId;
  NSInteger _nSelTabItemIdx;
  //NSString* _sSelHrtDataRng;
  
  //option view
  UIOptionView* _optSyncViwe;
  BOOL _bJustUpdActType;
  BOOL _bFinishSyncData;
  
  //sync hrate
  NSInteger _nLastIdx;
  NSInteger _nLastSyncIdx;
  
  BOOL _bFixHrtData;
  NSMutableArray* _pFixHrtItem;
  NSString* _sFixHrtItemLastDt;
  int _nFixHrtItemCnt;
  int _nFixHrtItemIdx;
  
  NSInteger _nFixHrateId;
}

- (void)viewDidLoad {
  [super viewDidLoad];
  // Do any additional setup after loading the view.
  self.view.backgroundColor =  [UIColor whiteColor];//[UIColor colorWithWhite:0.125 alpha:0.5];
    UIImageView *iView = [[UIImageView alloc] initWithFrame:self.view.frame];
    iView.contentMode = UIViewContentModeScaleAspectFill;
    iView.image = [UIImage imageNamed:@"ic-mainbkgd"];
    [self.view insertSubview:iView atIndex:0];
  [self setBodyMeasInfo];
  [self reloadHrateData];
    
    _bStartBleMeas = NO;
    AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    _ncitBleDev = pApp.m_ncitBleDev;
    //_ncitBleDev.bleDelegate = self;
    _bIsSuptBLe = pApp.m_bSupportBle;
    
    
    //UIImage* iProf = [pApp getImageScale:@"ic-list.png" scale: 0.4];
    //UIBarButtonItem *profButton = [[UIBarButtonItem alloc] initWithImage:iProf style:UIBarButtonItemStylePlain target:self action:@selector(mainAction:)];
    //self.navigationItem.leftBarButtonItem = leftButton;
    //self.navigationItem.rightBarButtonItem = profButton;
    
    CGRect frame = [[UIScreen mainScreen] bounds];
    CGFloat W = frame.size.width;
    CGFloat H = frame.size.height;
    
    _dtMeasStart = nil;
    _dtLast =  nil;
    _dtMeas = nil;
    
    CGFloat yPos = (H > 1000)? 75.0f: 75.0f;
    [self initViewCtrls:yPos scrWdt:W scrHgt:H];
    
  for(int i=0;i<_nDurtBarNumber; i++) {
    _faHrate[i] = 0;
    _faBarHgt[i] = 0;
  }
  
  _faHrateMax = 0;
    
  /*_faHrate[0] = 0;//30;
  _faHrate[1] = 0;//200;
  _faHrate[2] = 0;//25;
  _faHrate[3] = 0;//15;
  _faHrate[4] = 0;//10;*/
    
    for(int i=0; i<_nDurtBarNumber; i++) {
        _afPointCoef[i] = 1.0 + i;
    }
    
    _actView = nil;
    _bNoChooseDev = NO;
    _nCountTick = 0;
    
  _pHrateItem = nil;
  _nSelHrateId = 0;
  _nSelTabItemIdx = pApp.m_nLstHrtIdx;
  
  _pHrtRng = nil;
  _pHrtItem = nil;
  _pSyncItem = nil;
  
  _nSyncTotalPack = 0;
  _nSyncCurrentPack = 0;
  _progView = nil;
  
  _nSyncPos = 0;
  
  _bSyncGetReqst = YES;
  _bSyncGetNotNeed = NO;
  _bMadeRcdMark = NO;
  _bSyncSvrError = NO;
  
  _nHrateId = 0;
  _dicSyncHrate = [[NSMutableDictionary alloc] init];
  
  _nCurSyncHrateId = 0;
  _sIniSyncHrateId = nil;
  _sNewSyncHrateId = nil;
  _bUpdHrateId = NO;
  _bSyncError = NO;
  _sLastHrateId = @"0";
  
  [self.view addSubview:_ddlHrdList];
  _bFinishSyncData = NO;
  
  //debug®
  //[pApp updateHrateItemHrateIds:@"3" toId:@"-2"];
  
  _optSyncViwe = nil;
  _bJustUpdActType = NO;
  //_pSyncHrate = nil;
  
  _nLastIdx = 0;
  _nLastSyncIdx = 0;
  
  _bFixHrtData = NO;
  _pFixHrtItem = nil;
  _sFixHrtItemLastDt = nil;
  _nFixHrtItemCnt = 0;
  _nFixHrtItemIdx = 0;
  
  _nFixHrateId = 0;
  
  NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
  [userSetting synchronize];
  [userSetting setInteger:0 forKey:kSync_LastDldIdx];
}

- (void) initViewCtrls:(CGFloat) yPos scrWdt:(CGFloat) W scrHgt:(CGFloat)H
{
  BOOL bIpad = H > 1000;
  BOOL bWider = W > 320;
  BOOL bIp6p = W >= 414;
  BOOL bIp5s = H > 480;
  BOOL bIp4s = H <= 480;
  
  _bIpad = bIpad;
  _bIp6p =  bIp6p;
  _bIp6 = W == 375;
  
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    
    _lblMsg = [[UILabel alloc] initWithFrame:CGRectMake(20, yPos-(bIp4s?15:0), W-40, 25)];
    _lblMsg.textColor = DefaultColor;
    _lblMsg.font = [UIFont systemFontOfSize:16.0];
    _lblMsg.backgroundColor = [UIColor clearColor];
    _lblMsg.textAlignment = NSTextAlignmentCenter;//bIpad? NSTextAlignmentCenter: NSTextAlignmentRight;
    _lblMsg.text = NSLocalizedString(@"Heart Rate Record:", nil);
    [self.view addSubview:_lblMsg];

  
  CGFloat fHgt = bIpad?44:bIp6p?40:bWider?38:33;
  CGFloat fWid = W - (bIpad?W*0.45:4) - fHgt * 0.3;
  CGFloat yyPos = yPos + (bIpad?24:bIp6p?28:bWider?28:bIp5s?28:16);//(bIp4s?15:30);
    UIImage* iDorpDown = [UIImage imageNamed:@"ic-ddlist.png"];
  //_ivDropdwon = [[UIImageView alloc] initWithFrame:CGRectMake(bIpad?20:(W-fWid)/2, yyPos, fWid, fHgt)];
  _ivDropdwon = [[UIImageView alloc] initWithFrame:CGRectMake(30, yyPos, fWid * 3 / 4, fHgt)];
  _ivDropdwon.image = iDorpDown;
  [self.view addSubview:_ivDropdwon];
  UITapGestureRecognizer *ivSingleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapDropDown)];
  ivSingleTap.numberOfTapsRequired = 1;
  [_ivDropdwon setUserInteractionEnabled:YES];
  [_ivDropdwon addGestureRecognizer:ivSingleTap];
    
    _lblDropDownList = [[UILabel alloc] initWithFrame:CGRectMake(33, yPos+(bIp4s?19:34), W-(bIpad?W/2:80) * 3 / 4, 25)];
    _lblDropDownList.textColor = [UIColor grayColor];
    _lblDropDownList.font = [UIFont systemFontOfSize: 13.0];
    _lblDropDownList.backgroundColor = [UIColor clearColor];
    _lblDropDownList.textAlignment = NSTextAlignmentLeft;
    _lblDropDownList.text = NSLocalizedString(@"Tap to Select", nil);
    [self.view addSubview:_lblDropDownList];
    
    //CGFloat xPos = 22;
  CGFloat xPos = bIpad?22:bIp6p?8:bWider?6:bIp5s?4:2;
  fWid =  W-xPos-(bWider?6:bIp5s?4:2);
  fHgt = bIpad?H*1/2: H-yPos-80;
  if(bIpad)
    fWid = 402;
  _ddlHrdList = [[NIDropDownList alloc] initWithFrame:CGRectMake(xPos, yPos + 58, fWid, fHgt) type:101];
  _ddlHrdList.delegate = self;
    
    _lblTotalTimeTip = [[UILabel alloc] initWithFrame:CGRectMake(20, yPos + (bIp4s?60:80), W/3.0, 40)];
    _lblTotalTimeTip.textColor = DefaultColor;
    _lblTotalTimeTip.font = Regular(16);
    _lblTotalTimeTip.backgroundColor = [UIColor clearColor];
    _lblTotalTimeTip.textAlignment = NSTextAlignmentLeft;
    _lblTotalTimeTip.text = NSLocalizedString(@"Total Time:", nil);
    [self.view addSubview:_lblTotalTimeTip];
    
    _lblTotalTimeVal = [[UILabel alloc] initWithFrame:CGRectMake((bIp4s?90:110), yPos + (bIp4s?60:80), W/2.0, 40)];
    _lblTotalTimeVal.textColor = DefaultColor;
    _lblTotalTimeVal.font = [UIFont boldSystemFontOfSize: bWider?36.0:28.0];
    _lblTotalTimeVal.backgroundColor = [UIColor clearColor];
    _lblTotalTimeVal.textAlignment = NSTextAlignmentLeft;
    _lblTotalTimeVal.text = @"0:00:00";
    [self.view addSubview:_lblTotalTimeVal];
  
  //zone tipbIpadΩ
  _lblZoneTip = [[UILabel alloc] initWithFrame:CGRectMake(W-(bIpad?65:58), yPos + (bIp4s?72:92), 50, 25)];
  _lblZoneTip.textAlignment = NSTextAlignmentCenter;
  _lblZoneTip.font = [UIFont systemFontOfSize:14.0];
  _lblZoneTip.textColor = DefaultColor;
  _lblZoneTip.text = NSLocalizedString(@"ZONE", nil);
  //_lblZoneTip.backgroundColor = [UIColor orangeColor];
  [self.view addSubview:_lblZoneTip];
  
  //delete
  CGFloat fIconSize = bIpad?48:(bIp4s?32:32);
  UIImage* iBtn = [[UIImage imageNamed:@"act-delete.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  _btnDelete = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  _btnDelete.frame = CGRectMake(W-fIconSize*1.5, yPos + (bIpad?64:84), fIconSize, fIconSize);
  [_btnDelete setBackgroundImage:iBtn forState:UIControlStateNormal];
  [_btnDelete addTarget:self action:@selector(tapDeleteRcd:) forControlEvents:UIControlEventTouchUpInside];
  [self.view addSubview:_btnDelete];
  _btnDelete.hidden = YES;
  
  //act type
  _ivActType = [[UIImageView alloc] initWithFrame:CGRectMake(W-fIconSize*3+(bIpad?-220:bWider?-15:-4), /*yPos + (bIpad?64:84)*/yPos+(bIp4s?65:bIpad?68:85), fIconSize, fIconSize)];
  [self.view addSubview:_ivActType];
  ivSingleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onActTypeTap)];
  ivSingleTap.numberOfTapsRequired = 1;
  [_ivActType setUserInteractionEnabled:YES];
  [_ivActType addGestureRecognizer:ivSingleTap];
  
    fHgt =  bIpad? (H/2.8):(bWider? H/3.2: H/3.6);
    _pViewCurve = [[UICurveView alloc] initWithFrame:CGRectMake(5, yPos+(bIp4s? 100:120), W-12, fHgt) hBar: YES];
    _pViewCurve.bViewDataRcd = YES;
    _pViewCurve.dataSource = self;
    _pViewCurve.delegate = self;
    
  /*short nMaxHrt = 210 - _nAgeYear / 2 - _fBodyWgt * 0.05;
    if(_nSexNum == 1)
        nMaxHrt += 4;
    float nRngLow = nMaxHrt * _FitHR_RngMin;
    float nRngUpp = nMaxHrt * _FitHR_RngMax;
    [_pViewCurve setFitnessHrates:nRngLow maxHrt:nRngUpp];*/
  
  //viewWillAppear already do that
  short nMaxHrt = [pApp calHrateFitnessRng:NO];
  if(pApp.m_bodyInfo.nMaxBpm != nMaxHrt)
    nMaxHrt = (float)pApp.m_bodyInfo.nMaxBpm;
  
  //[_pViewCurve setFitnessHrates:(float)nMaxHrt];
  [self.view addSubview:_pViewCurve];
    
    //total point
    _lblTotalPtTip = [[UILabel alloc] initWithFrame:CGRectMake(bIpad?90:12, yPos +fHgt + (bIp4s? 95:125), W/4.0+15, 40)];
    _lblTotalPtTip.textColor = DefaultColor;
    _lblTotalPtTip.font = [UIFont systemFontOfSize: bWider?15.0:12.0];
    _lblTotalPtTip.backgroundColor = [UIColor clearColor];
  _lblTotalPtTip.textAlignment = NSTextAlignmentLeft;//bIpad?NSTextAlignmentCenter:NSTextAlignmentLeft;
  _lblTotalPtTip.lineBreakMode = NSLineBreakByWordWrapping;
  _lblTotalPtTip.numberOfLines = 2;
    _lblTotalPtTip.text = @"INTENSITY\nPOINTS"; //Total Intensity";
//    [self.view addSubview:_lblTotalPtTip];
    
    _lblTotalPtVal = [[UILabel alloc] initWithFrame:CGRectMake(W/4.0 + (bIpad?-30:bWider?8:5), yPos + fHgt + (bIp4s? 100:130), W/4.0+5, 40)];
    _lblTotalPtVal.textColor = DefaultColor;
    _lblTotalPtVal.font = [UIFont boldSystemFontOfSize:  bWider?28.0:24.0];
    _lblTotalPtVal.backgroundColor = [UIColor clearColor];
    _lblTotalPtVal.textAlignment = NSTextAlignmentCenter;
    _lblTotalPtVal.text = @"000";
//    [self.view addSubview:_lblTotalPtVal];
    
    //avt point per min
    _lblAvgPtMinTip = [[UILabel alloc] initWithFrame:CGRectMake(W/2.0 + 10, yPos + fHgt + (bIp4s? 100:130), W/4.0+0, 40)];
    _lblAvgPtMinTip.textColor = DefaultColor;
    _lblAvgPtMinTip.font = Regular(16);
    _lblAvgPtMinTip.backgroundColor = [UIColor clearColor];
    _lblAvgPtMinTip.textAlignment = bIpad?NSTextAlignmentRight:NSTextAlignmentCenter;
    _lblAvgPtMinTip.text = NSLocalizedString(@"CALs/Min", nil);
    [self.view addSubview:_lblAvgPtMinTip];
    
    _lblAvgPtMinVal = [[UILabel alloc] initWithFrame:CGRectMake(W*3.0/4.0-0, yPos + fHgt + (bIp4s? 100:130), W/4.0+0, 40)];
    _lblAvgPtMinVal.textColor = DefaultColor;
    _lblAvgPtMinVal.font = [UIFont boldSystemFontOfSize:  bWider?28.0:24.0];
    _lblAvgPtMinVal.backgroundColor = [UIColor clearColor];
    _lblAvgPtMinVal.textAlignment = NSTextAlignmentCenter;
    _lblAvgPtMinVal.text = @"0.0";
    [self.view addSubview:_lblAvgPtMinVal];
    
    //tpp view
    fHgt = bIpad? (fHgt * 4.0 / 6.0) : (fHgt * 3.0/ 6.0);
    //CGFloat fWid = W - (bIpad? 30: 50);
  fWid = W - (bIpad? 100: bIp6p?65:bWider?75: 56);
    yPos += fHgt + (bWider?270: (bIp4s?200:240));
    if (bIp4s)
        fHgt -= 10;
    else if(bIpad)
        yPos += 15;
    else if(H == 736)
        yPos += 20;
    
  //_pViewTpp = [[UICurveView alloc] initWithFrame:CGRectMake(bIpad?30: 28,  yPos, fWid, fHgt) hBar: NO];
  _pViewTpp = [[UICurveView alloc] initWithFrame:CGRectMake(bIpad?10:2, yPos, fWid, fHgt) hBar: NO];
  _pViewTpp.bViewDataRcd = YES;
  _pViewTpp.dataSource = self;
  _pViewTpp.delegate = self;
  
  //[_pViewTpp setFitnessHrates:nMaxHrt];
  [self.view addSubview:_pViewTpp];
    
    
    //CGFloat ySyncPos = bWider? 270: 240;
    //if(bIpad)
    //ySyncPos += 105;
    xPos = W - (bIpad? 100: (bIp4s?50:58));
    
    //bottom line and text
    yPos = H * 5.0 / 6.0;
    CGRect rt;
    UIImage* iCon = [[UIImage imageNamed:@"ic-horline.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    fHgt =  iCon.size.height  * 2 / 3; //W * iCon.size.height / iCon.size.width;
    rt.origin.x = 0;
    rt.origin.y =   yPos;
    rt.size.height = 1;
    rt.size.width = W;
    _ivhLine  = [[UIView alloc] initWithFrame:rt];
    _ivhLine.backgroundColor = [UIColor grayColor];
    _ivhLine.alpha = LineA;
    
//    [_ivhLine setImage:iCon];
    [self.view addSubview:_ivhLine];
    
    iCon = [[UIImage imageNamed:@"ic-verline.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  fHgt =  iCon.size.width * 2 / 3;
    rt.origin.x = W / 3.0 - fHgt / 2.0;
    rt.origin.y = rt.origin.y + 15;
//    rt.size.height = H - rt.origin.y - 10;
    rt.size.height = 0.5;
    rt.size.width = fHgt;//iCon.size.width;
//    _ivvLine1  = [[UIView alloc] initWithFrame:rt];
    _ivvLine1  = [[UIView alloc] initWithFrame:CGRectMake(W / 3, CGRectGetMaxY(_ivhLine.frame), LineH, 500)];
    _ivvLine1.backgroundColor = [UIColor grayColor];
    _ivvLine1.alpha = LineA;
//    [_ivvLine1 setImage:iCon];
    [self.view addSubview:_ivvLine1];
    
    
  rt.origin.x = W * 2.0 / 3.0 - fHgt / 2.0;
    rt.size.height = 1;
  //NSURLSessionConfiguration* cnfgSession = [NSURLSessionConfiguration defaultSessionConfiguration];
  //[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @"HrateSync"];
  _ivvLine2  = [[UIView alloc] initWithFrame:CGRectMake(W / 3 * 2, CGRectGetMaxY(_ivhLine.frame), LineH, 500)];
    _ivvLine2.backgroundColor = [UIColor grayColor];
    _ivvLine2.alpha = LineA;
//  [_ivvLine2 setImage:iCon];
  [self.view addSubview:_ivvLine2];
    
    //text
    fWid = bIpad?  W/6.0-5: W/3.0-5;
    xPos = bIpad? W/20.0 : W/80.0; //5;
    CGFloat fDelata = bIpad? 65:45;
    if(bIp4s)
        fDelata -= 10;
    //    _lblAvgHrateTip = [[UILabel alloc] initWithFrame:CGRectMake(xPos,  yPos+(bIp4s?5:15), fWid, 30)];
//    _lblAvgHrateTip = [[UILabel alloc] initWithFrame:CGRectMake(xPos,  yPos + fDelata + 15, fWid, 30)];
    _lblAvgHrateTip = [[UILabel alloc] initWithFrame:CGRectMake(xPos,  H  / 18 * 16.8, fWid, 30)];
    _lblAvgHrateTip.textColor = [UIColor blackColor];
    _lblAvgHrateTip.font = [UIFont systemFontOfSize:14.0];
    _lblAvgHrateTip.backgroundColor = [UIColor clearColor];
    _lblAvgHrateTip.textAlignment = NSTextAlignmentCenter;
    _lblAvgHrateTip.text = NSLocalizedString(@"Avg HR", nil);
    _lblAvgHrateTip.lineBreakMode = YES;
    [self.view addSubview:_lblAvgHrateTip];
    
    //    _lblAvgHrateVal =[[UILabel alloc] initWithFrame:CGRectMake(xPos,  yPos + fDelata, fWid-30, 40)];
//    _lblAvgHrateVal =[[UILabel alloc] initWithFrame:CGRectMake(xPos,  yPos+(bIp4s?5:15), fWid-30, 40)];
    _lblAvgHrateVal =[[UILabel alloc] initWithFrame:CGRectMake(xPos,  H  / 9 * 7.8, fWid-30, 40)];
    _lblAvgHrateVal.textColor = DefaultColor;
    _lblAvgHrateVal.font = Bold(H / 34);
    _lblAvgHrateVal.backgroundColor = [UIColor clearColor];
    _lblAvgHrateVal.textAlignment = NSTextAlignmentCenter;
    _lblAvgHrateVal.text = @"--- bpm";
    _lblAvgHrateVal.lineBreakMode = YES;
    _lblAvgHrateVal.centerX = _lblAvgHrateTip.centerX;
    [self.view addSubview:_lblAvgHrateVal];
    //_lblAvgHrateVal.backgroundColor = [UIColor blueColor];
    
    _lblAvgHrateUnit = [[UILabel alloc] initWithFrame:CGRectMake(xPos + fWid-35,  yPos + fDelata + 12, 30, 20)];
    _lblAvgHrateUnit.textColor = DefaultColor;
    _lblAvgHrateUnit.font = [UIFont boldSystemFontOfSize: 12.6];
    _lblAvgHrateUnit.textAlignment = NSTextAlignmentLeft;
    _lblAvgHrateUnit.text = @"bpm";
    _lblAvgHrateUnit.centerY = _lblAvgHrateVal.centerY;
    _lblAvgHrateUnit.lineBreakMode = YES;
    
//    [self.view addSubview:_lblAvgHrateUnit];
    //_lblAvgHrateUnit.backgroundColor = [UIColor redColor];
    
    
    xPos += W / 3.0;
    _lblMaxHrateTip = [[UILabel alloc] initWithFrame:CGRectMake(xPos, yPos + (bIp4s?5:15), fWid, 30)];
    _lblMaxHrateTip.textColor = [UIColor blackColor];
    _lblMaxHrateTip.font = [UIFont systemFontOfSize:14.0];
    _lblMaxHrateTip.backgroundColor = [UIColor clearColor];
    _lblMaxHrateTip.textAlignment = NSTextAlignmentCenter;
    _lblMaxHrateTip.text = NSLocalizedString(@"Max HR", nil);
    _lblMaxHrateTip.centerY = _lblAvgHrateTip.centerY;
    [self.view addSubview:_lblMaxHrateTip];
    
    _lblMaxHrateVal = [[UILabel alloc] initWithFrame:CGRectMake(xPos, yPos + fDelata, fWid - 30, 40)];
    _lblMaxHrateVal.textColor = DefaultColor;
    _lblMaxHrateVal.font = Bold(H / 34);
    _lblMaxHrateVal.backgroundColor = [UIColor clearColor];
    _lblMaxHrateVal.textAlignment = NSTextAlignmentCenter;
    _lblMaxHrateVal.text = @"--- bpm";
    _lblMaxHrateVal.centerY = _lblAvgHrateVal.centerY;
    _lblMaxHrateVal.centerX = _lblMaxHrateTip.centerX;
    [self.view addSubview:_lblMaxHrateVal];
    
    _lblMaxHrateUnit = [[UILabel alloc] initWithFrame:CGRectMake(xPos + fWid-35,  yPos + fDelata + 12, 30, 20)];
    _lblMaxHrateUnit.textColor = DefaultColor;
    _lblMaxHrateUnit.font = [UIFont boldSystemFontOfSize: 12.6];
    _lblMaxHrateUnit.backgroundColor = [UIColor clearColor];
    _lblMaxHrateUnit.textAlignment = NSTextAlignmentLeft;
    _lblMaxHrateUnit.text = @"bpm";
    _lblMaxHrateUnit.lineBreakMode = YES;
    _lblMaxHrateUnit.centerY = _lblAvgHrateVal.centerY;
//    [self.view addSubview:_lblMaxHrateUnit];
    
    xPos += W / 3.0;
    _lblCalBurnTip = [[UILabel alloc] initWithFrame:CGRectMake(xPos, yPos + (bIp4s?5:15), fWid, 30)];
    _lblCalBurnTip.textColor = [UIColor blackColor];
    _lblCalBurnTip.font = [UIFont systemFontOfSize:14.0];
    _lblCalBurnTip.backgroundColor = [UIColor clearColor];
    _lblCalBurnTip.textAlignment = NSTextAlignmentCenter;
    _lblCalBurnTip.text = NSLocalizedString(@"Cals Burned", nil);
    _lblCalBurnTip.centerY = _lblAvgHrateTip.centerY;
    [self.view addSubview:_lblCalBurnTip];
    
    _lblCalBurnVal = [[UILabel alloc] initWithFrame:CGRectMake(xPos, yPos + fDelata, fWid, 40)];
    _lblCalBurnVal.textColor = DefaultColor;
    _lblCalBurnVal.font = Bold(H / 34);
    _lblCalBurnVal.backgroundColor = [UIColor clearColor];
    _lblCalBurnVal.textAlignment = NSTextAlignmentCenter;
    _lblCalBurnVal.centerY = _lblAvgHrateVal.centerY;
    _lblCalBurnVal.text = @"---";
    [self.view addSubview:_lblCalBurnVal];
    
//    [self.view addSubview:_ddlBleDevice];
    
  
  xPos = W - (bIpad? 98: (bWider?60:50));
  yPos = yPos + fHgt / 2.0 - (bIpad?162:bIp6p?95:bWider?75:bIp5s?72:85);
  if(bIp4s)
    yPos += 20;
  //iBtn = [[UIImage imageNamed:@"btn-hrtDnld.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; //@"btn-sync-g.png"
     UIImage *hrtDnldImg = [[UIImage imageNamed:@"btn-hrtDnld.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  _btnSyncTpp = [UIButton buttonWithType:UIButtonTypeCustom];
    
//  _btnSyncTpp.frame = CGRectMake(xPos, yPos+25, bIpad?72:(bWider?56:48), bIpad?72:(bWider?56:48));
    _btnSyncTpp.frame = CGRectMake(xPos, yPos+25, self.view.frame.size.width / 9, self.view.frame.size.width / 9);
    [_btnSyncTpp setImage:hrtDnldImg forState:UIControlStateNormal];
    _btnSyncTpp.imageView.contentMode = UIViewContentModeScaleAspectFit;
  //[_btnSyncTpp setBackgroundImage:hrtDnldImg forState:UIControlStateNormal];
    _btnSyncTpp.centerY = _pViewTpp.centerY + _pViewTpp.frame.size.height / 3;
  [_btnSyncTpp addTarget:self action:@selector(onTapStartSync:) forControlEvents:UIControlEventTouchUpInside];
  [self.view addSubview:_btnSyncTpp];
  
  //tips
  CGFloat fTipxPos = _btnSyncTpp.frame.origin.x;
  CGFloat fTipyPos = _btnSyncTpp.frame.origin.y;
  if(bIp6p)
    fTipyPos += 3;
  else if(bIp4s)
    fTipxPos += 2;
  else if(!bWider)
    fTipxPos -= 5;
  _lblSyncData = [[UILabel alloc] initWithFrame:CGRectMake(fTipxPos - (bIp4s?14:10), fTipyPos + (bIpad?80:bWider?60:(bIp4s?50:55))-20, bIpad?92:(bIp4s?68:76), 44)];
  _lblSyncData.textColor = [UIColor whiteColor];
  _lblSyncData.font = [UIFont systemFontOfSize:bWider?12.0:10.5];
  _lblSyncData.backgroundColor = [UIColor clearColor];
  _lblSyncData.textAlignment = NSTextAlignmentCenter;
  _lblSyncData.lineBreakMode = NSLineBreakByWordWrapping;
  _lblSyncData.numberOfLines = 2;
  _lblSyncData.text = NSLocalizedString(@"HRM\n RECORD", nil);//@"Download";
//  [self.view addSubview:_lblSyncData];
    
    /*_barColors = @[[[UIColor blueColor] colorWithAlphaComponent:0.5],
     [[UIColor greenColor] colorWithAlphaComponent:0.5],
     [[UIColor yellowColor]colorWithAlphaComponent:0.5],
     [[UIColor orangeColor] colorWithAlphaComponent:0.5],
     [[UIColor redColor] colorWithAlphaComponent:0.5]];*/
}

- (void) createNetConnSession
{
  NSURLSessionConfiguration* cnfgSession = [NSURLSessionConfiguration defaultSessionConfiguration];// [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @"HrateSync"];
  cnfgSession.timeoutIntervalForRequest = 30.0;
  cnfgSession.timeoutIntervalForResource = 30.0;
  _netSession = [NSURLSession sessionWithConfiguration:cnfgSession delegate: self delegateQueue: nil];
}

- (void) viewWillAppear:(BOOL)animated
{
  [self createNetConnSession];
  
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  short nMaxHrt = [pApp calHrateFitnessRng: NO];
  if(pApp.m_bodyInfo.nMaxBpm != nMaxHrt) {
    [_pViewCurve setFitnessHrates:(float)pApp.m_bodyInfo.nMaxBpm];
    //[_pViewTpp setFitnessHrates:(float)pApp.m_bodyInfo.nMaxBpm];
    [_pViewTpp setFitnessHrates:(float)pApp.m_bodyInfo.nMaxBpm];
  }
  else {
    [_pViewCurve setFitnessHrates:(float)nMaxHrt];
    [_pViewTpp setFitnessHrates:(float)nMaxHrt];
  }
  
  //_pHrtData = [pApp loadHrateData:_nBodyId from:nil to:nil sort:NO last:NO syncDld:NO];
  [self showHrtData:_pHrtData];
  //[_pViewCurve setNeedsDisplay];
  //[_pViewTpp reloadData];
  
  [_pViewCurve setNeedsDisplay];
  [_pViewTpp setNeedsDisplay];
  
  _colBtnTitle = [UIColor grayColor];//[UIButton appearance].titleLabel.textColor;
  [[UIButton appearance] setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
}

- (void) viewWillDisappear:(BOOL)animated
{
  if(_bUpdHrateId) {
    [self onTapStopSync];
  }
  //[_netSession invalidateAndCancel];
  
  [[UIButton appearance] setTitleColor:_colBtnTitle forState:UIControlStateNormal];
  
  if(_nSyncPos > 1) {
    NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
    [userSetting setInteger:_nSyncPos-1 forKey: kSync_LastSyncIdx];
    [userSetting synchronize];
  }
  //_ncitBleDev.bleDelegate = nil;
  /*if(_nSyncPos > 0 && _nCurSyncHrateId != 0) {
    NSInteger nToId = _nCurSyncHrateId;
    AppDelegate* pApp = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    NSString* sToId = (_sNewSyncHrateId == nil)?_sIniSyncHrateId:_sNewSyncHrateId;
    if( sToId != nil)
      nToId = sToId.integerValue;
    [pApp updHrateSyncState:_nCurSyncHrateId toId:nToId lastIdx:_nSyncPos];
  }*/
}

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
  _lblMsg.text = NSLocalizedString(@"No enough memory!", nil);
  AudioServicesPlaySystemSound(1112);
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/
- (void)onActTypeTap
{
  //_lblMsg.text = @"Act Type tap";
  _bJustUpdActType = YES;
  NSInteger nIdx = _nSelTabItemIdx;
  //NSString* sKey = [NSString stringWithFormat:@"%ld", _nSelTabItemIdx];
  NSInteger nHrateId = _nSelHrateId;
  NSString* sMsg = _lblDropDownList.text;
  [self showSyncOption:(NSInteger)nHrateId idx: nIdx msg:sMsg type:1];
}

- (void) setBodyMeasInfo/*:(N_GroupInfo*) body*/
{
    AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    LoginBodyInfo* bodyInfo = pApp.m_bodyInfo;
    if(bodyInfo == nil) {
        _nBodyId = 0;
        return;
    }
    
    _nBodyId = bodyInfo.m_nBodyId;
    _nAgeYear = bodyInfo.nYearAge;
    
    //float fVal = bodyInfo.fBodyWgt;
    //if(bodyInfo.nWgtUn != 0)
    //fVal *= _LbtoKg;
    
    _fBodyWgt = bodyInfo.fBodyWgt;
    if(bodyInfo.nWgtUn == 2)
        _fBodyWgt *= _LbtoKg;
    _nHgtMm = bodyInfo.nHgtMm;
    
    _nSexNum = bodyInfo.nGender;
    _nExeLvl = bodyInfo.nActLvl;
}

-(void)mainAction:(id)sender  
{  
    AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [pApp enterPageWithRes:@"bodyProfViewCtrl"];
  
  if(_bUpdHrateId) {
    [self onTapStopSync];
    _lblMsg.text = NSLocalizedString(@"Sync upoload end!", nil);
  }
}

- (void) onTapDropDown
{
  if([_ddlHrdList isPopup]) {
      [_ddlHrdList hideDropDownList];
      _lblMsg.text = NSLocalizedString(@"Cancel", nil);
  }
  else {
    [_ddlHrdList popupDropDownList];
  }
  AudioServicesPlaySystemSound(1109);
}

- (short)getActTypeIdx:(NSInteger)nIdx
{
  if(nIdx >= _pHrtData.count || nIdx < 0)
     return 0;
  H_Rate* pRate = [_pHrtData objectAtIndex:nIdx];
  short nActType = pRate.actType.shortValue;
  return nActType;
}

- (void) fillDropdownList:(NSMutableArray*)pHrtData dtfmt:(NSDateFormatter*) dtFmt
{
  //[dtFmt setDateFormat:@"MM/dd/yy h:mm:ss"];
  
  NSMutableDictionary *dirDevMember = [[NSMutableDictionary alloc] init];
  NSUInteger nCount = pHrtData.count;
  for(NSUInteger i=0; i<nCount; i++) {
    H_Rate* hrData = (H_Rate*)[pHrtData objectAtIndex:i];
    if(hrData == nil)
      continue;
    NSString* sId = hrData.hRateId.stringValue;
    if(_nSelHrateId == 0)
      _nSelHrateId = sId.integerValue;
    //NSString* sVal = sId;
    NSString* sVal = [dtFmt stringFromDate: hrData.hEnterDate];
        
    
    //if(sVal == nil)
      //sVal = @"NULL";
    if(_bIpad)
      sVal = [sVal stringByAppendingString:(hrData.bMemory.boolValue?@"\n M \t\t  ":@"\n R \t\t  ")];
    else if(_bIp6p)
      sVal = [sVal stringByAppendingString:(hrData.bMemory.boolValue?@"\n M \t\t  ":@"\n R \t\t  ")];
    else  if(_bIp6)
      sVal = [sVal stringByAppendingString:(hrData.bMemory.boolValue?@"\n M \t\t  ":@"\n R \t\t  ")];
    else
      sVal = [sVal stringByAppendingString:(hrData.bMemory.boolValue?@"\n M \t\t  ":@"\n R \t\t  ")];
    
    NSString* sTo = [dtFmt stringFromDate:hrData.hEndDate];
    if(sTo != nil) {
      NSRange rng = [sTo rangeOfString:@" "];
      if(rng.location != NSNotFound) {
        sVal = [sVal stringByAppendingString:@" "];
        sVal = [sVal stringByAppendingString:[sTo substringFromIndex:rng.location+1]];
      }
    }
    
    //long nLastIdx = (long)hrData.nLastUpdIdx.integerValue;
    sVal = [sVal stringByAppendingFormat:@"->%ld", (long)hrData.hRateId.integerValue];
    sVal = [sVal stringByAppendingFormat:@" LstIdx:%ld&st=%d", (long)hrData.nLastUpdIdx.integerValue, hrData.nSyncType.shortValue];
    [dirDevMember setValue: sVal forKey:sId];
  }
  
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSString* sLastHrtId = [NSString stringWithFormat:@"%ld", (long)pApp.m_nLastHrtId];
  [_ddlHrdList setListData:dirDevMember curSel:sLastHrtId];// @"0";
  //[_ddlHrdList popupDropDownList];
}

- (BOOL) comparatorEnterDate
{
  return NO;
}

- (void) updFixHrtDataToSvr:(NSString*) sHrateId
{
  _bFixHrtData = YES;
  _nFixHrtItemIdx = 0;
  NSInteger nBodyId = _nBodyId;
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSDictionary *measData = @{
                             @"BodyId": [NSString stringWithFormat:@"%ld", (long)nBodyId],
                             @"m_nHrateId" : sHrateId,
                             @"hType" : @"51"
                             };
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
  request.timeoutInterval = 20.0;
  
  
  // 6.发送连接请求
  //[NSURLConnection connectionWithRequest:request delegate:self];
  NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  [task resume];
  //NSLog(@"Fix HRM Data session resume");
}

- (void) sendFixHrtDateEndTime:(NSString*) sHrateId dtEnd:(NSString*) sDtEnd
{
  NSInteger nBodyId = _nBodyId;
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSDictionary *measData = @{
                             @"BodyId": [NSString stringWithFormat:@"%ld", (long)nBodyId],
                             @"m_nHrateId" : sHrateId,
                             @"m_sEnd" : sDtEnd,
                             @"hType" : @"52"
                             };
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
  request.timeoutInterval = 20.0;
  
  
  // 6.发送连接请求
  //[NSURLConnection connectionWithRequest:request delegate:self];
  NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  [task resume];
}

- (void) sendFixHrtItemnRecd:(NSString*) sHrateId
{
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
  if(_nFixHrtItemIdx >= _nFixHrtItemCnt) {
    //_bFixHrtData = NO;
    [pApp updateHrateToSvrStateforLastIdx:_nBodyId hRateId:_nFixHrateId lastIdx:-1];
    [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
    dispatch_async(dispatch_get_main_queue(), ^{
      //[_ddlHrdList resetCellBgrd:_nSelTabItemIdx];
      H_Rate* pHrate =  [_pHrtData objectAtIndex:_nSelTabItemIdx];
      pHrate.nLastUpdIdx = [NSNumber numberWithInteger:-1];
      [pApp refreshCoreDataItems:pHrate];
      [pApp.dtFmt setDateFormat:@"MM/dd/yy HH:mm:ss"];
      [self fillDropdownList:_pHrtData dtfmt:pApp.dtFmt];
      //[pApp.dtFmt setDateFormat:sInitDtFmt];
      
      _lblMsg.text = NSLocalizedString(@"Upload Miss Data OK!", nil);
    });
    _nFixHrateId = 0;
    return;
  }
  H_RateItem* pHrtItem = [_pFixHrtItem objectAtIndex:_nFixHrtItemIdx];
  if(pHrtItem == nil) {
    _nFixHrateId = 0;
    //_bFixHrtData = NO;
    [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
    return;
  }
 
  [pApp.dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss.SSS"];
  short nHrtBpm = pHrtItem.hRateValue.shortValue;
  NSString* sHrtTime = [pApp.dtFmt stringFromDate:pHrtItem.hRateTime];
  
  NSInteger nBodyId = _nBodyId;
 
  NSDictionary *measData = @{
                             @"BodyId": [NSString stringWithFormat:@"%ld", (long)nBodyId],
                             @"m_nHrateId" : sHrateId,
                             @"HrateVal" : [NSString stringWithFormat:@"%d", nHrtBpm],
                             @"MeasTime" : sHrtTime,
                             @"hType" : @"53"
                             };
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
  request.timeoutInterval = 20.0;
  
  
  // 6.发送连接请求
  //[NSURLConnection connectionWithRequest:request delegate:self];
  NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  [task resume];
  _nFixHrtItemIdx++;
  
  [pApp.dtFmt setDateFormat:sInitDtFmt];
}

- (NSString *) niDropDownDelegateMethod: (NIDropDownList *) sender
{
  NSString* sHrateId = sender.sSelValId;
  if(_bUpdHrateId) {
    [self onTapStopSync];
    
    _lblMsg.text = NSLocalizedString(@"Sync upoload end!", nil);
    return sHrateId;
  }
  if(_sLastHrateId != nil && ![_sLastHrateId isEqualToString:sHrateId]) {
    NSUserDefaults *
    
    userSetting = [NSUserDefaults standardUserDefaults];
    [userSetting setInteger:0 forKey: kSync_LastDldIdx];
    [userSetting synchronize];
    _nLastIdx = 0;
  }
  
  _sLastHrateId = sHrateId;
  if(sHrateId != nil)
    _nFixHrateId = sHrateId.integerValue;
  else
    return @"0";
  //else if(_nFixHrateId != 0)
    //sHrateId = [NSString stringWithFormat:@"%ld", _nFixHrateId];
  
  [sender hideDropDownList];
  _lblMsg.text = NSLocalizedString(@"Selected", nil);
  if(_lblMsg.textColor != [UIColor whiteColor])
    _lblMsg.textColor = [UIColor whiteColor];
  
  //clear data
  for(int i= 0; i<_nDurtBarNumber; i++) {
    _faHrate[i] = 0;
    _faBarHgt[i] = 0;
  }

  //[_pViewCurve showHrateItem:nil];
  //[_pViewTpp resetData];
  
    
    /*NSUInteger nCount = pHrateItem.count;
    NSDate* dtLast = nil;
    for(NSUInteger i=0; i<nCount; i++) {
        H_RateItem* pItem = [pHrateItem objectAtIndex:i];
        short nHrate = pItem.hRateValue.shortValue;
        int nIdx = [_pViewTpp getHrateRngIdx:nHrate];
        NSDate* dtMeas = pItem.hRateTime;
        if(nIdx > 0 && dtLast != nil) {
            double dDelta = [dtMeas timeIntervalSinceDate:dtLast];
            fPoints += nIdx * dDelta;
        }
        dtLast = dtMeas;
    }*/
    
  //float fDurTime = [_pViewCurve showHrateItem:pHrateItem];
  //[_pViewTpp showHrateDurTime: pHrateItem durTime:_faHrate];
  NSString* sText = sender.sSelText;
  if([sText rangeOfString:@"M"].location == NSNotFound) {
    sText =[sText stringByReplacingOccurrencesOfString: @"\n R \t\t  " withString: @" -"];
    sText = [sText stringByAppendingString:@" (R)"];
  }
  else {
    sText =[sText stringByReplacingOccurrencesOfString: @"\n M \t\t  " withString: @" -"];
    sText = [sText stringByAppendingString:@" (M)"];
  }
  //[_lblDropDownList performSelectorOnMainThread:@selector(setText:) withObject:sText waitUntilDone:NO];
  [_lblDropDownList performSelector:@selector(setText:) withObject:sText afterDelay:0];
  //_sSelHrtDataRng = sText;
  
  //show sel data
  NSInteger nIdx = sHrateId.integerValue;
  _nSelHrateId = nIdx;
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  //debug
  //NSDate* dtVal = [NSDate date];
  //BOOL bExists = [pApp checkExistsHrateStart:5 start:dtVal];
  //debug
  
  pApp.m_nLastHrtId = nIdx;
  NSMutableArray* pHrateItem = [NSMutableArray arrayWithArray:[pApp loadHrateItemData:nIdx last:NO]];
  if(pHrateItem.count == 0 && nIdx > 0) {
  //if(nIdx == -65) {
    _nSelHrateId = -1;
    pHrateItem = [NSMutableArray arrayWithArray:[pApp loadHrateItemData:_nSelHrateId last:NO]];
    while (pHrateItem.count == 0 && _nSelHrateId > -2000) {
      _nSelHrateId--;
       pHrateItem = [NSMutableArray arrayWithArray: [pApp loadHrateItemData:_nSelHrateId last:NO]];
    }
    if(pHrateItem.count > 0) {
      [pApp updateHrateDataHrateId:nIdx toId: _nSelHrateId];
      [pApp updateHrateItemHrateIds:nIdx toId: _nSelHrateId];
      
      [self reloadHrateData];
      [self showHrtData:_pHrtData];
    }
    else {
      _nSelHrateId = nIdx;
    }
  }
  else {
   _nSelHrateId = nIdx;
  }
  //temp
  //else if(nIdx >= 45) {
    //[pApp updHrateSyncState: nIdx toId: nIdx lastIdx:3000];
  //}
  //temp
  
  //test start
  /*if(nIdx == 23907) {
    [pApp updHrateSyncState: nIdx toId: -1 lastIdx:0];
    [pApp updateHrateItemHrateIds:nIdx toId: -1];
   
    [self reloadHrateData];
    [self showHrtData:_pHrtData];
  }*/
  //for debug rem
  /*else if(nIdx == -1) {
    [pApp updHrateSyncState:-1 toId:nIdx lastIdx:-1];
    [pApp updateHrateItemHrateIds:-1 toId: nIdx];
    
    [self reloadHrateData];
    [self showHrtData:_pHrtData];
  }*/
  //test end
  
  //test start
  /*[pApp updHrateSyncState:nIdx toId:-2 UdldOk:NO lastIdx:0];
  [pApp updateHrateItemHrateIds:sHrateId toId: @"-2"];*/
  //test end
  H_Rate* pHrate =  [_pHrtData objectAtIndex:sender.nSelectIdx];
  NSDate* dtStart = pHrate.hEnterDate;
  
  //item end date time
  /*NSUInteger nItemCount = pHrateItem.count;
  if(nItemCount > 0) {
    if([self fixHrateStartEndTime:sText item:pHrateItem start:dtStart app:pApp hrtId:sHrateId]) {
      H_RateItem* pItemLast = [pHrateItem objectAtIndex:0];
      dtStart = pItemLast.hRateTime;

    }
  }*/
  
  
  [self showHrateItem:pHrateItem start:dtStart];
  //actType and comm
  nIdx = sender.nSelectIdx;
  _nSelTabItemIdx = nIdx;
  [self showActType:nIdx];
  pApp.m_nLstHrtIdx = nIdx;
  
  BOOL bNetOk = [pApp isNetWorkConnAvailable];
  BOOL bNeedFix = _nFixHrateId > 0 && pHrate.nLastUpdIdx.integerValue == 0;
  if(bNeedFix && bNetOk) {
    [self updFixHrtDataToSvr: sHrateId];
     _lblMsg.textColor = [UIColor whiteColor];
  }
  else if(!bNetOk) {
    _lblMsg.text = NSLocalizedString(@"No WAN Network!", nil);
    _lblMsg.textColor = [UIColor redColor];
  }
  
  return sHrateId;
}

- (BOOL) fixHrateStartEndTime:(NSString*)sText item:(NSMutableArray*)pHrateItem start:(NSDate*)dtStart app:(AppDelegate*) pApp hrtId:(NSString*)sHrateId
{
  BOOL bOK = NO;
  NSUInteger nItemCount = pHrateItem.count;
  H_RateItem* pItemLast = [pHrateItem objectAtIndex:0];
  NSDate* dtBegin = pItemLast.hRateTime;
  if(dtBegin == nil)
    dtBegin = dtStart;
  pItemLast = [pHrateItem objectAtIndex:nItemCount-1];
  NSDate* dtEnd = pItemLast.hRateTime;
  if(dtBegin == nil || dtEnd == nil)
    return NO;
  
  NSTimeInterval dtDelta1 = [dtBegin timeIntervalSinceDate:dtStart];
  
  NSString* sShowEnd = sText;
  NSRange rng1 = [sShowEnd rangeOfString:@" "];
  NSRange rng2 = [sShowEnd rangeOfString:@" "];
  NSDateFormatter* dtFmt = pApp.dtFmt;
  NSString* sInitFmt = dtFmt.dateFormat;
  [dtFmt setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  
  if(rng1.location != NSNotFound && rng2.location != NSNotFound) {
    NSRange rng = NSMakeRange(rng1.location, 12);
    sShowEnd = [sShowEnd stringByReplacingCharactersInRange:rng withString:@" "];
    rng2 = [sShowEnd rangeOfString:@" ("];
    if(rng2.location != NSNotFound) {
      rng = NSMakeRange(rng2.location, 4);
      sShowEnd = [sShowEnd stringByReplacingCharactersInRange:rng withString:@""];
      
      [dtFmt setDateFormat:@"MM/dd/yy HH:mm:ss"];
      NSDate* dtShowEnd = [dtFmt dateFromString:sShowEnd];
      NSTimeInterval dtDelta2 = [dtEnd timeIntervalSinceDate:dtShowEnd];
      
      if(fabs((double)dtDelta1) > 10 || fabs((double)dtDelta2) > 10) {
        [dtFmt setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        bOK = [pApp fixHrateStartEndTime: sHrateId startTime:dtBegin endTime:dtEnd];
        if(bOK) {
          [dtFmt setDateFormat:@"MM/dd/yy HH:mm:ss"];
          NSString* sStart = [dtFmt stringFromDate:dtBegin];
          NSString* sEnd = [dtFmt stringFromDate:dtEnd];
          NSString* sDateRng = [NSString stringWithFormat:@"%@ - %@ (R)", sStart, sEnd];
          [self reloadHrateData];
          [dtFmt setDateFormat:@"MM/dd/yy HH:mm:ss"];
          [self fillDropdownList:_pHrtData dtfmt:dtFmt];
          
          [_lblDropDownList performSelector:@selector(setText:) withObject:sDateRng afterDelay:0];
        }
      }
    }
  }
  
  [pApp.dtFmt setDateFormat:sInitFmt];
  return bOK;
}

-(UIImage*) getActTypeImage:(NSInteger)nIdx
{
  if(_pHrtData.count <= nIdx)
    return [UIImage imageNamed:@"ic-empty.png"];
  
  UIImage* iActType = nil;
  H_Rate* pHrate =  [_pHrtData objectAtIndex:nIdx];
  if(pHrate != nil) {
    short nActType = pHrate.actType.shortValue;
    switch (nActType) {
      case 1:
        iActType = [UIImage imageNamed:@"act-walking.png"];
        break;
      case 2:
        iActType = [UIImage imageNamed:@"act-running.png"];
        break;
      case 3:
        iActType = [UIImage imageNamed:@"act-biking.png"];
        break;
      case 4:
        iActType = [UIImage imageNamed:@"act-climbing.png"];
        break;
      case 5:
        iActType = [UIImage imageNamed:@"act-group.png"];
        break;
        
      default:
        iActType = [UIImage imageNamed:@"act-rdques.png"];
        break;
    }
  }
  return iActType;
}

-(void) showActType:(NSInteger)nIdx
{
  //if(_bSyncGetNotNeed)
    //return;
  if(nIdx < 0 || nIdx >4)
    return;
  
  UIImage* iActType = [self getActTypeImage:nIdx];
  if(iActType != nil)
    _ivActType.image = iActType;
    
  [_ivActType setNeedsDisplay];
}

- (void) reloadHrateData
{
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateData:_nBodyId from:nil to:nil sort:NO last:NO syncDld:NO]];
  if(_pHrtData != nil && _pHrtData.count > 0) {
    NSUInteger nCount = _pHrtData.count;
    for(NSUInteger i=0; i<nCount; i++) {
      H_Rate* pRate = [_pHrtData objectAtIndex:i];
      //NSDate* dtBeg = pRate.hEnterDate;
      [pApp refreshCoreDataItems:pRate];
    }
  }
  //item refresh
  _pHrtItem = nil;
  if(pApp.m_nLastHrtId <= 0)
    _pHrtItem = [NSMutableArray arrayWithArray:[pApp loadHrateItem:_nBodyId from:nil to:nil sort:YES avg: NO last:NO sync:NO]];
  else
    _pHrtItem = [NSMutableArray arrayWithArray:[pApp loadHrateItemData:pApp.m_nLastHrtId last:NO]];
  if(_pHrtItem != nil && _pHrtItem.count > 0) {
    NSUInteger nCount = _pHrtItem.count;
    for(NSUInteger i=0; i<nCount; i++) {
      H_RateItem* pItem = [_pHrtItem objectAtIndex:i];
      [pApp refreshCoreDataItems:pItem];
    }
  }
  //[self showHrtData:_pHrtData];
  /*NSData dtMFmt
  [dtFmt setDateFormat:@"MM/dd/yy HH:mm:ss"];
  [self fillDropdownList:_pHrtData dtfmt:dtFmt];*/

}

- (void) sendSvrUserDelHrate:(NSInteger)nHrateId
{
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSDictionary *measData = @{
                             @"BodyId" : [NSString stringWithFormat:@"%ld", (long)_nBodyId],
                             @"m_nHrateId" : [NSString stringWithFormat:@"%ld", (long)nHrateId],
                             @"hType" : @"99"
                             };
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
  request.timeoutInterval = 20.0;
  
  
  // 6.发送连接请求
  //[NSURLConnection connectionWithRequest:request delegate:self];
  NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  [task resume];
}

- (void) deleteRowInvoke
{
  [self reloadHrateData];
  //_lblMsg.text = @"delete invoke";
  _ivActType.image = nil;
  for(int i= 0; i<_nDurtBarNumber; i++) {
    _faHrate[i] = 0;
    _faBarHgt[i] = 0;
  }
  [_pViewCurve showHrateItem:nil];
  [_pViewTpp showHrateItem:nil];
  
  _lblTotalTimeVal.text = @"0:00:00";
  _lblTotalPtVal.text= @"000";
  _lblAvgPtMinVal.text = @"0.0";
  
  if(![_lblDropDownList.text hasPrefix: @"--delete--"])
    _lblDropDownList.text = @"";
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
  BOOL isInside = YES;
  UITouch *touch = [touches anyObject];
    
  if(_ddlHrdList != nil && _ddlHrdList.isPopup) {
    CGPoint pt =[touch locationInView:_ddlHrdList];
    isInside = [_ddlHrdList pointInside:pt withEvent:event];
    if(!isInside) {
        [_ddlHrdList hideDropDownList];
        _lblMsg.text = NSLocalizedString(@"Cancel", nil);
    }
  }
  
  if(_optSyncViwe == nil)
    return;
  if(_optSyncViwe.hidden)
    return;
  
  CGPoint pt =[touch locationInView:_optSyncViwe];
  isInside = [_optSyncViwe pointInside:pt withEvent:event];
  if(!isInside) {
    [self stopOptTypeCtrl];
    _lblMsg.text = NSLocalizedString(@"Cancel", nil);
  }
}

- (void) showHrtData:(NSMutableArray*)pHrtData
{
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSUInteger nCount = pHrtData.count;
  if(nCount == 0) {
    _lblMsg.text = [NSString stringWithFormat:NSLocalizedString(@"No data for %@ %@", nil), pApp.m_bodyInfo.sFirst, pApp.m_bodyInfo.sLast]; // @"No any HRM meas. data";
    return;
  }
  else {
     _lblMsg.text = [NSString stringWithFormat:NSLocalizedString(@"HRM Record for %@ %@", nil), pApp.m_bodyInfo.sFirst, pApp.m_bodyInfo.sLast];
  }
  
    NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
    NSDateFormatter* _dtFmt = pApp.dtFmt;
    
    [_dtFmt setDateFormat:@"MM/dd/yy HH:mm:ss"];
  
  /*NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
  [_dtFmt setLocale:locale];
  [_dtFmt setDateFormat:@"MM/dd/yy hh:mm:ss"];*/
  
  [self fillDropdownList:pHrtData dtfmt:_dtFmt];
    
  //select first one and show it
  NSString* sHrateId = @"0";
  NSString* sText = nil;
  if(_nSelTabItemIdx >= 0)
    sText = [_ddlHrdList getItemText:_nSelTabItemIdx key:&sHrateId];
  else
    sText = [_ddlHrdList getItemText:0 key:&sHrateId];
  
  if([sText rangeOfString:@"M"].location == NSNotFound)
    sText =[sText stringByReplacingOccurrencesOfString: @"\n R \t\t  " withString: @" -"];
  else
    sText =[sText stringByReplacingOccurrencesOfString: @"\n M \t\t  " withString: @" -"];
  _lblDropDownList.text =  sText;
  
  if(pApp.m_nLastHrtId <= 0) {
    _ddlHrdList.sSelValId = sHrateId;
    pApp.m_nLastHrtId = sHrateId.integerValue;
  }
 
  //NSInteger nId = sHrateId.integerValue ;
  NSMutableArray* pHrateItem = [NSMutableArray arrayWithArray:[pApp loadHrateItemData:sHrateId.integerValue last:NO]];
 
  //H_Rate* pHrate =  [_pHrtData objectAtIndex:_ddlHrdList.nSelectIdx];
  if(pApp.m_nLstHrtIdx > _pHrtData.count-1)
    pApp.m_nLstHrtIdx =  _pHrtData.count-1;
  H_Rate* pHrate =  [_pHrtData objectAtIndex:pApp.m_nLstHrtIdx];
  if(pHrate == nil)
    return;
  NSDate* dtStart = pHrate.hEnterDate;
  
  [self showHrateItem: pHrateItem start:dtStart];
  
  //actType and comm
  NSInteger nLastHrtIdx = pApp.m_nLstHrtIdx;
  [self showActType:nLastHrtIdx]; //0
    
  [pApp.dtFmt setDateFormat:sInitDtFmt];
}

-(void) resetHrateDate:(H_RateItem*) hRateItem
{
  _dAvgHrate = 0.0;
  _nAvgHrate = 0;
  _nMaxHrate = 0;
  _nMinHrate = 1000;
  _fBurnedVal = 0.0;
}

- (void) showHrateItem:(NSMutableArray*) pHrateItem start:(NSDate*)dtStart
{
  if(pHrateItem == nil || pHrateItem.count < 1) {
    _lblTotalTimeVal.text = @"0:00:00";
    _lblTotalPtVal.text = @"000";
    _lblAvgPtMinVal.text =  @"0.0";
    _lblAvgHrateVal.text = @"---";
    _lblMaxHrateVal.text = @"---";
    _lblCalBurnVal.text = @"---";
    for(int i=0; i<_nDurtBarNumber; i++) {
      _faHrate[i] = 0;
      _faBarHgt[i] = 0;
    }
  
    [_pViewCurve resetData];
    [_pViewTpp showHrateItem:nil];
    return;
  }

    /*NSUInteger nCount = pHrateItem.count;
    NSDate* dtLast = nil;
    for(NSUInteger i=0; i<nCount; i++) {
        H_RateItem* pItem = [pHrateItem objectAtIndex:i];
        short nHrate = pItem.hRateValue.shortValue;
        int nIdx = [_pViewTpp getHrateRngIdx:nHrate];
        NSDate* dtMeas = pItem.hRateTime;
        if(nIdx > 0 && dtLast != nil) {
            double dDelta = [dtMeas timeIntervalSinceDate:dtLast];
            fPoints += nIdx * dDelta;
        }
        dtLast = dtMeas;
    }
    fPoints /= 60.0;*/
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  double dItemTime = [_pViewCurve showHrateItem:pHrateItem];
  
  H_RateItem* hItem = (H_RateItem*)pHrateItem.firstObject;
  NSInteger hRateId = hItem.hRateId.integerValue;
  NSMutableArray* maHrate = [NSMutableArray arrayWithArray:[pApp loadHrateInfo:hRateId]];
  double dDurTime = 0,  dDurElaps = 0.0;//[hRate.hEndDate timeIntervalSinceDate:hRate.hEnterDate];
  if(maHrate != nil && maHrate.count > 0) {
    H_Rate* hRate = (H_Rate*)[maHrate objectAtIndex:0];
    if(hRate != nil) {
      NSDate* dtBeg = hRate.hEnterDate;
      if((dtStart == nil && dtBeg != nil) || ([dtStart compare:dtBeg] == NSOrderedDescending) )
        dtStart = dtBeg;
      //NSDate* dtEnd = hRate.hEndDate;
      //dtMeas = hRate.hEndDate;
      if(hRate.hEndDate == nil)
        dDurTime = dItemTime;
      else if(dtStart != nil && hRate.hEndDate != nil)
        dDurTime = [hRate.hEndDate timeIntervalSinceDate:dtStart];
      else if(hRate.hEndDate != nil && hRate.hEnterDate != nil)
        dDurTime = [hRate.hEndDate timeIntervalSinceDate:hRate.hEnterDate];
      
      _dtMeasStart = hRate.hEnterDate;
      _dtLast = hRate.hEnterDate;
    }
    dDurElaps = dDurTime;
    
    [self resetHrateDate:hItem];
    NSUInteger nCount = pHrateItem.count;
    NSString* sItemDtRng = @"";
    
    if(nCount > 0) {
      H_RateItem* objFirst = [pHrateItem firstObject];
      H_RateItem* objLast = [pHrateItem lastObject];

      NSDate* dtBegin = objFirst.hRateTime;
      double dDelta = [dtBegin timeIntervalSinceDate:_dtMeasStart];
      if(fabs(dDelta) > 10) {
        _dtMeasStart = dtStart;
      }
      
      //NSDate* pDate = objLast.hRateTime;
      dDurTime = [objLast.hRateTime timeIntervalSinceDate:dtStart];
  
      //dDurElaps = dDurTime;
      if(dDurTime > 0 && dDurTime > dDurElaps && dDurTime <= 46800) {
        dDurElaps = dDurTime;
        
        NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
        [pApp.dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss"];
        NSString* sItemStart = [pApp.dtFmt stringFromDate:objFirst.hRateTime];
        [pApp.dtFmt setDateFormat:@"HH:mm:ss"];
        NSString* sItemEnd = [pApp.dtFmt stringFromDate:objLast.hRateTime];
        sItemDtRng = [NSString stringWithFormat:@"%@ ~ %@", sItemStart, sItemEnd];
        //_lblDropDownList.text = sItemDtRng;
        [_lblDropDownList performSelector:@selector(setText:) withObject:sItemDtRng afterDelay:0];
        [pApp.dtFmt setDateFormat:sInitDtFmt];
      }
    }
    
    _dtLast = dtStart;
    for(NSUInteger i = 0; i<nCount; i++) {
      hItem = (H_RateItem*)[pHrateItem objectAtIndex:i];
      short nHrate = [hItem.hRateValue shortValue];
      _dtMeas = hItem.hRateTime;
      
      //test
      /*[pApp.dtFmt setDateFormat:@"HH:mm:ss.SSS"];;
      NSString* pMeas = [pApp.dtFmt stringFromDate:_dtMeas];
      if([pMeas isEqualToString:@"11:27:08.000"]) {
        int n = 0;
      }*/
      //test
      
      [self setHrateOviewData:nHrate];
      _dtLast = hItem.hRateTime;
      //test
      if(i > 220) {
        _dtLast = _dtMeas;
      }
    }
    if(_fBurnedVal > 5)
      _lblCalBurnVal.text = [NSString localizedStringWithFormat:@"%.0f", _fBurnedVal];
    else if(_fBurnedVal > 1)
      _lblCalBurnVal.text = [NSString localizedStringWithFormat:@"%.1f", _fBurnedVal];
    else
      _lblCalBurnVal.text = [NSString localizedStringWithFormat:@"%.2f", _fBurnedVal];
    
    _nAvgHrate = (short)(_dAvgHrate + 0.5);
    pApp.m_nCurtAvgHrt = _nAvgHrate;
    _lblAvgHrateVal.text = [NSString stringWithFormat:@"%d bpm", _nAvgHrate];
    _lblMaxHrateVal.text = [NSString stringWithFormat:@"%d bpm", _nMaxHrate];
  }
  hItem = (H_RateItem*)pHrateItem.lastObject;
  if(hItem != nil)
    pApp.m_nLastHrate = [hItem.hRateValue shortValue];
 
  if(maHrate.count == 0)
    dDurTime = dItemTime;
     
    
    
  //double fDurTime = [_pViewCurve showHrateItem:pHrateItem] + 0.50;
    //fDurTime = [_pViewTpp showHrateItem:pHrateItem];

  //_faHrateMax = [_pViewTpp showHrateDurTime: pHrateItem durTime:&pHrate];
  _faHrateMax = [_pViewTpp showHrateDurTime: pHrateItem start:dtStart];
  CGFloat* pBandDur = [_pViewTpp getBandDurTime];
  for(int i=0; i<_nDurtBarNumber; i++) {
    _faHrate[i] = pBandDur[i];
  }
    
    double fPoints = 0;
    for(int i=0; i<_nDurtBarNumber; i++) {
        fPoints += _faHrate[i] * _afPointCoef[i] / 60.0;
    }
    fPoints += 0.005;
  
  _lblTotalTimeVal.text = [pApp getHourMinSec:dDurElaps]; //dDurTime;
    if(fPoints >= 100)
      _lblTotalPtVal.text = [NSString stringWithFormat:@"%.1f", fPoints];
    else
      _lblTotalPtVal.text = [NSString stringWithFormat:@"%.1f", fPoints];
  
  if(_fBurnedVal > 0) {
    CGFloat fCalMin = _fBurnedVal;
    if(fCalMin > 1000)
      fCalMin /= 1000.0;
    float fMinDur = roundf((dDurTime / 60) * 100000) / 100000.0;
    fCalMin = _fBurnedVal / fMinDur;
    //fCalMin = _fBurnedVal * 60 / dDurTime;
    _lblAvgPtMinVal.text = [NSString stringWithFormat:@"%.2f", fCalMin];
  }
  
  _faHrateMax = [self getBarHgeMax];
  [_pViewTpp reloadData];
  [_pViewTpp setNeedsDisplay];
}
/**************************/
/* data source and delete */
/**************************/
- (CGFloat) getBarHgeMax{
  CGFloat fMaxVal = 0;
  for (NSInteger i=0; i<_nDurtBarNumber; i++) {
    //if(fMaxVal < _faHrate[i] * _afPointCoef[i])
      //fMaxVal = _faHrate[i] * _afPointCoef[i];
    if(fMaxVal < _faHrate[i])
      fMaxVal = _faHrate[i];
  }
  
  if(fMaxVal > 0) {
    BOOL bNormized = fMaxVal > _BarHgtUpLimit;
    for (NSInteger i=0; i<_nDurtBarNumber; i++) {
      if(bNormized)
        _faBarHgt[i] = _faHrate[i] * _BarHgtUpLimit / fMaxVal;
      else
        _faBarHgt[i] = _faHrate[i] / 2.5;
      
      //_faBarHgt[i] *= _afPointCoef[i];
    }
  }
  
  return fMaxVal;
}

- (NSUInteger) numberOfBarsInBarChart:(UICurveView *)barChart
{
    return 5;
}

- (CGFloat) barChart:(UICurveView *)barChart valueForBarAtIndex:(NSUInteger)index
{
  CGFloat fBarHgt = _faBarHgt[index];
  return fBarHgt;
  /*CGFloat fTime = _faHrate[index] * _afPointCoef[index];
  if(fTime == 0.0)
    return fTime;
  
  if(_faHrateMax == 0.0)
    _faHrateMax = _pViewTpp.m_fMaxDurVal;
  if(_faHrateMax != 0)
    fTime = fTime * 35.0 / _faHrateMax;
  
  return fTime;*/
}

- (CGFloat)barChart:(UICurveView *)barChart xposForBarAtIndex:(NSUInteger)index
{
    CGFloat xPos = index * 10;
    return xPos;
}

/*- (UIColor *)barChartColor:(NSInteger)nIdx
 {
 return _barColors[nIdx];
 }*/

/*- (short)barChart:(UICurveView *)barChart hRateForBarAtIndex:(NSUInteger)index
 {
 return 10 * index;
 }*/

- (UIColor *)barChart:(UICurveView *)barChart colorForBarAtIndex:(NSUInteger)index
{
    return [UIColor redColor];
}

- (NSString *)barChart:(UICurveView *)barChart xLabelForBarAtIndex:(NSUInteger)index
{
    return @"4.5";
}

- (NSString *)barChart:(UICurveView *)barChart textForBarAtIndex:(NSUInteger)index
{
    return @"50";
}

- (int) totalRcvedCount
{
    return 0;
}

- (double) HrateTimeInterval
{
  return 2.0;//[_dtMeas timeIntervalSinceDate:_dtLast];
}

- (double) setHrateOviewData:(short)nHrate
{
  if(_dtMeasStart == nil)
    return 0.0;
  //if(nHrate > _pViewCurve.m_yMax || nHrate < _pViewCurve.m_yMin)
    //return  0.0;
  
  if(nHrate > _nMaxHrate)
    _nMaxHrate = nHrate;
  if(nHrate < _nMinHrate)
    _nMinHrate = nHrate;
  
  //AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  double dTotalSecond = [_dtMeas timeIntervalSinceDate:_dtMeasStart];
  double dDurSecs = dTotalSecond; 
  //_lblTotalTimeVal.text = [pApp getHourMinSec:dTotalSecond];;
  
  double dDurSeconds = [_dtMeas timeIntervalSinceDate:_dtLast];
  dTotalSecond -= dDurSeconds;
  if(dTotalSecond < 0)
    dTotalSecond = 0.0; //dDurSeconds;
  double dSum = dTotalSecond + dDurSeconds;
  
  if(_nAvgHrate == 0) {
    _dAvgHrate = nHrate;
    _nAvgHrate = nHrate;
  }
  else if(dSum != 0) {
    _dAvgHrate = (_dAvgHrate * dTotalSecond + nHrate * dDurSeconds) / dSum;
  }
  
  //_lblAvgHrateVal.text = [NSString stringWithFormat:@"%d", _nAvgHrate];
  //_lblMaxHrateVal.text = [NSString stringWithFormat:@"%d", _nMaxHrate];
  
  [self calDisplayBurnedVal:nHrate];
  return dDurSecs;
}

- (double) calDisplayBurnedVal:(short)nRate
{
  if(_dtMeas == nil)
    _dtMeas = [NSDate date];
  if(_dtLast == nil)
    return _fBurnedVal;
  
  double dDurSeconds = [_dtMeas timeIntervalSinceDate:_dtLast];
  
  //cal calories
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  ViewController* pMainView = pApp.m_pRootViewCtrl;
  float fWgt = pMainView.fBodyLastWgt;
  short nWu = pMainView.nBodyLastWu;
  if(fWgt != 0 && nWu != 1)
    fWgt *= _LbtoKg;
  else if(fWgt == 0) {
    fWgt = _fBodyWgt;
  }
  CGFloat fCalories = [self calBurnedCalories:nRate second:dDurSeconds wgt:fWgt age:_nAgeYear sex:_nSexNum];
  _fBurnedVal += fCalories * 1000.0;
  
  //NSString* sCalUnit = @"C";
  if(_fBurnedVal < 0) {
    _fBurnedVal = 0;
  }
  /*else if(_fBurnedVal > 1000) {
    _fBurnedVal /= 1000.0;
    sCalUnit = @"k-C";
  }*/
  //_lblCalBurnVal.text = [NSString stringWithFormat:@"%.1f %@", _fBurnedVal, sCalUnit];
  //_fBurnedVal = 1234.0;
  //_lblCalBurnVal.text = [NSString localizedStringWithFormat:@"%.0f", _fBurnedVal];
  
  //last hrate
  if(nRate > 0)  {
    _nLastHrate = (short)nRate;
  }
  
  return _fBurnedVal;
}

- (CGFloat) calBurnedCalories:(short) nHrate second:(double)dSec wgt:(double)dWgt age:(short)nAge sex:(short)nSex
{
  CGFloat fCalories = 0.0;
  if(nSex == 1) {
    fCalories = ((0.2017 * nAge + 0.1988 * dWgt + 0.6309 * nHrate - 55.0969) / 4.184) * (dSec / 60.0) / 1000.0;
  }
  else {
    fCalories = ((0.074 * nAge - 0.1263 * dWgt + 0.4472 * nHrate - 20.4022) / 4.184) * (dSec / 60.0) / 1000.0;
  }
  if(fCalories < 0)
    fCalories = 0;
  return fCalories;
}

- (void) syncRecvHrateData:(NSString*)sExistIds
{
  NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
  [userSetting synchronize];
  
  _bSyncError = NO;
  //_nSyncPos = 0;
  if(_nSyncPos <= 0)
    _nSyncPos = [userSetting integerForKey:kSync_LastDldIdx];
  if(_nSyncPos >= 1)
    _nSyncPos -= 1;
  _nSyncCurrentPack = _nSyncPos;
  _nHrateId = 0;
  _bSyncGetReqst = YES;
  
  _SynsSvrStep = 1;
  _lblMsg.text = NSLocalizedString(@"SYNC HRM Data (Download)...", nil);
  _lblMsg.textColor = [UIColor whiteColor];
  
  //syns get data from server
  [self setLastSyncPos];
  [self getHrateDataInfo: sExistIds];
}

-(void) getHrateDataInfo:(NSString*)sExistIds
{
  _nSyncTotalPack = 0;
  
  NSString* sUrl = [NSString stringWithFormat:@"Msync?id=%ld&exist=%@" , (long)_nBodyId, sExistIds];
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  /*(NSDictionary *measData = @{
                             @"exist":sExistIds
  };*/
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"GET" url:sUrl data:nil];
  request.timeoutInterval = 20.0;
  /*[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue]
                         completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {*/
  NSData *data= [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
  if (data != nil) {
     // handle response
     NSString* sRecv = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    if([sRecv rangeOfString:@"error"].location != NSNotFound) {
      _bSyncSvrError = YES;
      [self stopSyncProcess:NO];
      _lblMsg.text = NSLocalizedString(@"Communicate Exception with APP Server!", nil);//sRecv;
      return;
    }
     if(sRecv.length > 10) {
       [self stopSyncProcess:NO];
       return;
     }
     else if(sRecv.length == 0) {
         _lblMsg.text = NSLocalizedString(@"APP Server can not connected!", nil);
       _lblMsg.textColor = [UIColor redColor];
       
       _nSyncTotalPack = -1;
       [self stopSyncProcess:NO];
       return;
     }
     
     _nSyncTotalPack = sRecv.integerValue;
     if(_nSyncTotalPack > 0) {
       _bSyncGetNotNeed = NO;
       [self requestHrateData];
     }
     else {
       [pApp updateDldsHreteRecved:_nBodyId];
       [self reloadHrateData];
       [self showHrtData:_pHrtData];
       [self performSelectorOnMainThread:@selector(stopShowSyncCtrld:) withObject:[NSNumber numberWithBool:YES] waitUntilDone:NO];
     }
  }
  else {
    [self stopSyncProcess:NO];
    //AudioServicesPlayAlertSound(1109)
    
    [self UrlSessionTimeOut];
    AudioServicesPlaySystemSound(1112);
    return;
  }
   //}];
  
  /*NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
   [task resume];*/
}

- (void) noSyncDownloadTip:(NSString*)sMsg
{
  _lblMsg.text = sMsg;
}

- (void) requestHrateData {
  if(_bSyncError)
    return;
  
  _SynsSvrStep = 4;
  if(_nSyncPos > _nSyncTotalPack) {
    _nSyncPos = 0;
    //[self syncSendHrateData];
    [self stopSyncProcess:YES];
    return;
  }
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  
  NSString* sUrl = [NSString stringWithFormat:@"Msync?id=%ld", (long)_nBodyId];
  NSDictionary *measData = @{
                             @"BodyId" : [NSString stringWithFormat:@"%ld", (long)_nBodyId],
                             @"hType" : [NSString stringWithFormat:@"1"],
                             @"_nSyncPos" : [NSString stringWithFormat:@"%ld", (long)_nSyncPos]
                             };
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"PUT" url:sUrl data:measData];
  request.timeoutInterval = 20.0;
  
  
  // 6.发送连接请求
  //[NSURLConnection connectionWithRequest:request delegate:self];
  
   NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  [task resume];
}

- (BOOL) storeSyncGetHrateData:(NSData*)hData
{
  NSInteger nUpper = _nSyncCurrentPack - 0;
  if((nUpper > _nSyncTotalPack) || _nSyncTotalPack == 0) {
    _nSyncPos = 0;
    //[self syncSendHrateData];
    [self stopSyncProcess:YES];
    return NO;
  }
  [self performSelectorOnMainThread:@selector(showSyncProgress) withObject:nil waitUntilDone:NO];
  
  //NSString* sRecv = [[NSString alloc] initWithData:hData encoding:NSASCIIStringEncoding];
  
  NSError *e = nil;
  NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: hData options: NSJSONReadingMutableContainers error: &e];
  if(e != nil) {
    [self stopSyncProcess:YES];
    [self performSelectorOnMainThread:@selector(updAllRecvHrateLastUpdIdx:) withObject:nil waitUntilDone:YES];
    return NO;
  }
    
  for(NSDictionary *item in jsonArray) {
    //NSLog(@"Item: %@", item);
    NSString* sMemory = [item objectForKey:@"_sMemory"];
    NSString* dtStart = [item objectForKey: @"dtStart"];
    NSString* dtEnd = [item objectForKey:@"dtEnd"];
    NSString* sAct = [item objectForKey:@"_nActType"];
    NSString* sHrateId = [NSString stringWithFormat:@"%@", [item objectForKey:@"nHrateId"]];
    //NSInteger nHrateId = [item objectForKey:@"nHrateId"];
    NSString* sItemId = [item objectForKey:@"_nItemId"];
    NSString* sBpm = [item objectForKey:@"_nHrateVal"];
    NSString* sMeas = [item objectForKey:@"_sHrateTime"];
    
    NSInteger nHrateId = sHrateId.integerValue;
    _nCurSyncHrateId = nHrateId;
    
    //NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
    //NSInteger nLastSyncIdx = [userSetting integerForKey:kSync_LastDldIdx];
    
    if([_dicSyncHrate objectForKey:sHrateId] == nil/* && nLastSyncIdx == 0*/) {
      //AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
      //_pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateInfo:nHrateId]];
      [self storeSyncDownloadHrateData:sMemory start:dtStart end:dtEnd act: sAct hrateId:nHrateId itemId:sItemId.integerValue bpm:(short)sBpm.intValue meas:sMeas];
      [self requestHrateData];
      _nSyncPos++;
    }
    else {
      //[self setLastSyncPos];
      if([self storeSyncDownloadHrateItem: _nBodyId hrateId:nHrateId itemId:sItemId.integerValue bpm:(short)sBpm.intValue meas:sMeas]) {
        [self requestHrateData];
        _nSyncPos++;
      }
    }
  }
  return YES;
  
}

/*- (void) updateSyncHratePos:(AppDelegate*)pApp hrateId:(NSInteger)nHrateId hitemId:(NSInteger)nItemId bpm:(short)nBpm meas:(NSDate*)dtMeas
{
  //AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  if([pApp insertSyncHrateItemData:_nBodyId hrateId:nHrateId itemId:nItemId hRate:nBpm dtime:dtMeas] == nil) {
    //already exists
    H_Rate* pHrate = [[NSMutableArray arrayWithArray:[pApp loadHrateInfo:nHrateId]] objectAtIndex:0];
    NSInteger nLastIdx = pHrate.nLastUpdIdx.integerValue;
    if(nLastIdx > 0 && _nSyncPos > 0 && _nSyncPos <= nLastIdx) {
      _nSyncPos = nLastIdx + 1;
      _nSyncCurrentPack = _nSyncPos;
    }
  }
}*/

- (void) storeSyncDownloadHrateData:(NSString*)sMem start:(NSString*)sStart end:(NSString*)sEnd act:(NSString*)sAct hrateId:(NSInteger)nHrateId itemId:(NSInteger)nItemId bpm:(short)nBpm meas:(NSString*) sMeas
{
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
  [pApp.dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss.SSS"];
  
  if(_nHrateId != nHrateId) {
    _SynsSvrStep = 1;
    BOOL bMem = sMem.intValue == 1;
    short nAct = (short)sAct.intValue;
    NSDate* dtStart = [pApp.dtFmt dateFromString:sStart];
    NSDate* dtEnd = [pApp.dtFmt dateFromString:sEnd];
    dispatch_sync(dispatch_get_main_queue(), ^{
      [pApp insertSyncHrateData:_nBodyId hrateId:nHrateId start:dtStart end:dtEnd mem:bMem act:nAct];
      
      NSString* sKey = [NSString stringWithFormat:@"%ld", (long)nHrateId];
      [_dicSyncHrate setObject:sKey forKey:sKey];
    });
    //_sLastStartTime = [NSString stringWithString:sStart];
    
    _nHrateId = nHrateId;
    _nLastIdx = 0;
  }
  
  if(nHrateId > 0) {
    NSDate* dtMeas = [pApp.dtFmt dateFromString:sMeas];
    //[self performSelectorOnMainThread:@selector(updateSyncHratePos:hrateId:hitemId:bpm:meas) withObject:anObj waitUntilDone:YES];
    dispatch_async(dispatch_get_main_queue(), ^{
      //NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
      //NSInteger nLastSyncPos = [userSetting integerForKey:kSync_LastDldIdx];
      [pApp insertSyncHrateItemData:_nBodyId hrateId:nHrateId itemId:nItemId hRate:nBpm dtime:dtMeas];
      /*if(nLastSyncPos == 0) {
        if([pApp insertSyncHrateItemData:_nBodyId hrateId:nHrateId itemId:nItemId hRate:nBpm dtime:dtMeas] == nil) {
          //already exists
          NSMutableArray* pArray = [NSMutableArray arrayWithArray:[pApp loadHrateInfo:nHrateId]];
          if(pArray != nil && pArray.count > 0) {
            H_Rate* pHrate = [pArray objectAtIndex:0];
            //if(pHrate != nil)
              //[pApp refreshCoreDataItems:pHrate];
            NSInteger nLastIdx = pHrate.nLastUpdIdx.integerValue - 1;
            if(nLastIdx > 0 && _nSyncPos < nLastIdx) {
              _nSyncPos = nLastIdx;// + 1;
              _nSyncCurrentPack = _nSyncPos;
            }
          }
        }
      }
      //else {
      if(nLastSyncPos > 0) {
        _nSyncPos = nLastSyncPos;
        if(_nSyncPos >= 1)
          _nSyncPos -= 1;
        _nSyncCurrentPack = _nSyncPos;
      }*/
      _nLastIdx++;
    });
    /*if(nHrateId == 43) {
      int m = 1;
    }*/ //debug rem
  }
  
  [pApp.dtFmt setDateFormat:sInitDtFmt];
}

- (BOOL) storeSyncDownloadHrateItem:(NSInteger)nBodyId hrateId:(NSInteger)nHrateId itemId:(NSInteger)nItemId bpm:(short)nBpm meas:(NSString*) sMeas
{
  //NSInteger nLastIdx = -1;
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
  [pApp.dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss.SSS"];
  
  /*NSMutableArray* pArray = [NSMutableArray arrayWithArray:[pApp loadHrateInfo:nHrateId]];
  if(pArray != nil && pArray.count > 0) {
    H_Rate* pHrate = [pArray objectAtIndex:0];
    nLastIdx = pHrate.nLastUpdIdx.integerValue;
  }
  
  if(nLastIdx == -1) {
    return YES;
  }
  else if(nLastIdx > 0 && _nSyncPos > 0 && _nSyncPos <= nLastIdx) {
    _nSyncPos = nLastIdx;// + 1;
    _nSyncCurrentPack = _nSyncPos;
    [self requestHrateData];
    return NO;
  }*/
  
  if(nHrateId > 0) {
    NSDate* dtMeas = [pApp.dtFmt dateFromString:sMeas];
    dispatch_sync(dispatch_get_main_queue(), ^{
      [pApp insertSyncHrateItemData:_nBodyId hrateId:nHrateId itemId:nItemId hRate:nBpm dtime:dtMeas];
    });
    [pApp.dtFmt setDateFormat:sInitDtFmt];
    _nLastIdx++;
  }
  
  return YES;
}

- (void) syncSendHrateData:(NSInteger)nHrateId
{
  _bSyncGetReqst = NO;
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  //dispatch_sync(dispatch_get_main_queue(), ^{
  _lblMsg.text = NSLocalizedString(@"SYNC HRM Data (Upload)...", nil);
  _lblMsg.textColor = [UIColor whiteColor];
  
  if(nHrateId == 0) {
    //last one time
    NSInteger nLastHrtId = [pApp loadLastHrateId:_nBodyId sync:YES];
    
    _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateData:_nBodyId from:nil to:nil sort:YES last:NO syncDld:YES]];
    _pHrtRng = [NSMutableArray arrayWithArray:[pApp loadHrateRngData:_nBodyId from:nil to:nil sort:YES last:NO syncDld:YES]];
    _pSyncItem = [NSMutableArray arrayWithArray:[pApp loadHrateItemData:nLastHrtId last:NO]];
  }
  else {
    _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateInfo:nHrateId]];
    if(_pHrtData.count == 0 && nHrateId < 0) {
      nHrateId = _sNewSyncHrateId.integerValue;
      _nSelHrateId = nHrateId;
      _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateInfo:nHrateId]];

    }
    _pHrtRng = [NSMutableArray arrayWithArray:[pApp loadHrateRngInfo:nHrateId]];
    _pSyncItem = [NSMutableArray arrayWithArray:[pApp loadHrateItemData:nHrateId last:NO]];
    
    //test
    //[self sendHrateRng];
    //return;
  }
  
  //_pHrtItem = [pApp loadHrateItem:_nBodyId from:nil to:nil sort:YES avg: NO last:NO sync:YES];
  
  NSInteger nRngCount = (_pHrtRng.count > 0)? 1: 0;
  _nSyncTotalPack = _pHrtData.count + nRngCount + _pSyncItem.count;
  //_nSyncTotalPack = 2 + _pSyncItem.count;
   //});
  if(_nSyncTotalPack > 0) {
    H_Rate* pHrate = [_pHrtData objectAtIndex:0];
    if(pHrate != nil) {
      short nSyncType = pHrate.nSyncType.shortValue;
      NSInteger nLastIdx = pHrate.nLastUpdIdx.integerValue;
      _nLastSyncIdx = nLastIdx;
      //if(pHrate.bUpdOk.boolValue) {
      if(nLastIdx == -1) {
        if(nSyncType == 2)
          _lblMsg.text = NSLocalizedString(@"Already Uploaded to Server!", nil);
        else if(nSyncType==1)
          _lblMsg.text = NSLocalizedString(@"Already Downloaded From Server", nil);
        else
          _lblMsg.text = NSLocalizedString(@"Already Sync to Server!", nil);
        
        _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateData:_nBodyId from:nil to:nil sort:NO last:NO syncDld:NO]];
        AudioServicesPlaySystemSound(1109);
        return;
      }
      else if(nSyncType==1) {
        //update act type already then tips
        _lblMsg.text = NSLocalizedString(@"DownLoad Item, Please tap HRM RECORD", nil);
        
        _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateData:_nBodyId from:nil to:nil sort:NO last:NO syncDld:NO]];
        AudioServicesPlaySystemSound(1109);
        return;
      }
    }
    //_pSyncHrate = pHrate;
    
    NSString* sInitDrFmt = pApp.dtFmt.dateFormat;
    NSDateFormatter* dtFmt = pApp.dtFmt;
    [dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss"];
    NSString* sMsg = [NSString stringWithFormat:@"Sync Selected One: %@", [dtFmt stringFromDate:pHrate.hEnterDate]];
    _lblMsg.text = sMsg;
    [pApp.dtFmt setDateFormat:sInitDrFmt];
  }
  else {
    _lblMsg.text = NSLocalizedString(@"No Any Data Need Upload", nil);
    _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateData:_nBodyId from:nil to:nil sort:NO last:NO syncDld:NO]];
    AudioServicesPlaySystemSound(1109);

    return;
  }
  
  if(_bSyncGetReqst) {
    _nSyncPos = 0;
    _nSyncCurrentPack = 0;
  }
  
  if(_nSyncTotalPack > 0) {
    // 4.设置请求体（请求参数）
    // 创建一个描述订单信息的JSON数据
    NSDictionary *measData = @{
                               @"BodyId" : [NSString stringWithFormat:@"%ld", (long)_nBodyId],
                               @"hType" : @"0"
                               };
    NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
    request.timeoutInterval = 20.0;
    
    
    // 6.发送连接请求
    //[NSURLConnection connectionWithRequest:request delegate:self];
    NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
    [task resume];
    [self performSelectorOnMainThread:@selector(startConnActindicator:) withObject:@"Upload..." waitUntilDone:YES];
    NSLog(@"URL session resume");
  }
  else {
    [self stopSyncProcess:YES];
    //AudioServicesPlaySystemSound(1112);
    return;
  }
}

- (void) syncHrateRecvAct:(NSInteger)nHrateId actType:(short)nActType
{
  if(nHrateId <= 0)
    return;
  
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSDictionary *measData = @{
                             @"BodyId" : [NSString stringWithFormat:@"%ld", (long)_nBodyId],
                             @"m_nHrateId" : [NSString stringWithFormat:@"%ld", (long)nHrateId],
                             @"_nActType" : [NSString stringWithFormat:@"%i", nActType],
                             @"hType" : @"4"
                             };
  
  
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
  //[NSURLConnection connectionWithRequest:request delegate:self];
  NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  request.timeoutInterval = 20;
  
  [task resume];
}

- (void) tapDeleteRcd:(id)sender
{
  if(_pHrtData.count == 0) {
    _lblMsg.text = NSLocalizedString(@"No any data for delete", nil);
    _btnDelete.hidden = YES;
    return;
  }
  [_ddlHrdList deleteHrateRow:_nSelHrateId row:_nSelTabItemIdx];
  _lblDropDownList.text = @"--delete--";
  _btnDelete.hidden = YES;
}

- (void) startSyncHrateData:(NSString*)sMsg
{
  [self performSelectorOnMainThread:@selector(startConnActindicator:) withObject:NSLocalizedString(@"Wait...", nil) waitUntilDone:YES];
  
  _SynsSvrStep = 0;
  _bMadeRcdMark = NO;
  
  _nSyncPos = 0;
  _sIniSyncHrateId = nil;
  _sNewSyncHrateId = nil;
  _bUpdHrateId = NO;
  _sLastHrateId = @"0";
  
  _lblMsg.textColor = [UIColor whiteColor];
  [_pViewTpp hideHgtBar:YES];
  
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  //form exists data
  _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateData:_nBodyId from:nil to:nil sort:YES last:NO  syncDld:YES]];
  NSUInteger nCount = _pHrtData.count;
  [_dicSyncHrate removeAllObjects];
  
  NSString* sExistIds = @"(";
  for(NSUInteger i=0; i<nCount; i++) {
    H_Rate* pHrate = [_pHrtData objectAtIndex:i];
    NSString* sKey = pHrate.hRateId.stringValue;
    [_dicSyncHrate setObject:/*pHrate*/sKey forKey:sKey];
    
    BOOL bALreadyInc = [sExistIds rangeOfString:sKey].location != NSNotFound;
    if(sKey.integerValue < 0 || bALreadyInc)
      continue;
    
    if(sExistIds.length > 1)
      sExistIds = [sExistIds stringByAppendingFormat:@",%@", sKey];
    else
      sExistIds = [sExistIds stringByAppendingFormat:@"%@", sKey];
  }
  sExistIds = [sExistIds stringByAppendingString:@")"];
  
  if(_progView == nil) {
    CGRect frame = [[UIScreen mainScreen] bounds];
    CGFloat W = frame.size.width;
    
    CGRect rt = _pViewTpp.frame;
    CGFloat yPos = rt.origin.y + 25;
    _progView = [[UIProgressView alloc] initWithFrame:CGRectMake(20, yPos, W-((W>700)?40:80), 10)];
    [self.view addSubview:_progView];
  }
  _progView.hidden = NO;
  _progView.progress = 0.0;
  
  
  //[NSThread detachNewThreadSelector:@selector(startActIndicator) toTarget:self withObject:nil];
  //[_actView startAnimating];
  
  
  [self syncRecvHrateData:sExistIds];
}

- (void) onTapStartSync:(id)sender
{
  AppDelegate* pApp = (AppDelegate*)[[UIApplication sharedApplication] delegate];
  if(![pApp isNetWorkConnAvailable]) {
    _lblMsg.text = NSLocalizedString(@"WAN network is not Aviable!", nil);
    _lblMsg.textColor = [UIColor redColor];
    AudioServicesPlaySystemSound(1112);
    return;
  }
  _bSyncSvrError = NO;
  _bJustUpdActType = NO;
  _bSyncGetNotNeed = NO;

  _lblMsg.textColor = DefaultColor;
  [self performSelectorOnMainThread:@selector(startSyncHrateData:) withObject:NSLocalizedString(@"Wait...", nil) waitUntilDone:YES];
}

/*-(void) stopIndicator
{
  
}*/

-(void) onTapStopSync
{
  NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
  [userSetting setInteger:_nSyncPos-1 forKey: kSync_LastDldIdx];
  [userSetting synchronize];
  
  _bSyncSvrError = YES;
  [_netSession invalidateAndCancel];
  //[[UIButton appearance] setTitleColor:_colBtnTitle forState:UIControlStateNormal];
  
  //dispatch_sync(dispatch_get_main_queue(), ^{
    //[_netSession finishTasksAndInvalidate]; //invalidateAndCancel];
    _lblMsg.text = @"Stop Sync Data!";
    _lblMsg.textColor = [UIColor redColor];
    
    //[_actView stopAnimating];
    [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
    _btnSyncTpp.hidden = NO;
  //});
  _netSession = nil;
  
  //re create it
  [NSThread sleepForTimeInterval:0.5];
  [self createNetConnSession];
}

- (void) startConnActindicator:(NSString*)sMsg
{
  if(sMsg != nil)
    _lblMsg.text = sMsg;
  
  if(_actView == nil) {
    CGRect rt = _btnSyncTpp.frame;
    //rt.origin.x += rt.size.width - rt.size.height * 2;
    //rt.size.width = rt.size.height;
    _actView = [[UIActivityIndicatorView alloc] initWithFrame:rt];
    _actView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
    _actView.hidesWhenStopped = YES;
    
    //[_actView addTarget:self action:@selector(tapDeleteRcd:) forControlEvents:UIControlEventTouchUpInside];
    UITapGestureRecognizer *ivSingleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapStopSync)];
    ivSingleTap.numberOfTapsRequired = 1;
    [_actView setUserInteractionEnabled:YES];
    [_actView addGestureRecognizer:ivSingleTap];
    
    [self.view addSubview:_actView];
  }
  _lblSyncData.hidden = YES;
  _btnSyncTpp.hidden = YES;
  [_actView performSelectorOnMainThread:@selector(startAnimating) withObject:nil waitUntilDone:NO];
}

/*- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
  
}
 
 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
 {
 
 }*/

- (void) UrlSessionTimeOut
{
  NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
  [userSetting setInteger:_nSyncPos-1 forKey: kSync_LastDldIdx];
  [userSetting synchronize];
  _nLastIdx = _nSyncPos-1;
  
   dispatch_sync(dispatch_get_main_queue(), ^{
     _bUpdHrateId = NO;
     _lblMsg.text = NSLocalizedString(@"APP Server Connection Terminate/Exception!", nil);
     _lblMsg.textColor = [UIColor redColor];

     //[_actView stopAnimating];
     if(_actView != nil)
       [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
     _btnSyncTpp.hidden = NO;
   });
}

- (void) updateHrateLastUpdIdx
{
  if(_nSyncPos > 0 && _nCurSyncHrateId != 0) {
    NSInteger nFrId = _nCurSyncHrateId;
    NSInteger nToId = _nCurSyncHrateId;
    
    if(_sIniSyncHrateId != nil)
      nFrId = _sIniSyncHrateId.integerValue;
    if(_sNewSyncHrateId != nil)
      nToId = _sNewSyncHrateId.integerValue;
    
    AppDelegate* pApp = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    NSInteger nLastIdx = _nSyncPos - 1;
    
    [pApp updHrateSyncState:nFrId toId:nToId lastIdx:nLastIdx];
    if(nFrId != nToId)
      [pApp updHrateSyncState:nToId toId:nToId lastIdx:nLastIdx];
    if(!_bSyncGetReqst) {
      [pApp updateHrateItemHrateIds:nFrId toId:nToId];
      if(nFrId != nToId)
        [pApp updateHrateItemHrateIds:nToId toId:nToId];
    }
    
    
    NSMutableArray* pArray = [NSMutableArray arrayWithArray:[pApp loadHrateInfo:nToId]];
    if(pArray != nil && pArray.count > 0) {
      H_Rate* pRate = [pArray objectAtIndex:0];
      [pApp refreshCoreDataItems:pRate];
    }
    dispatch_sync(dispatch_get_main_queue(), ^{
      [self reloadHrateData];
      if(!_bSyncError)
        [self showHrtData:_pHrtData];
    });
    
    //last download pos
    nLastIdx = _nSyncPos;
    NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
    [userSetting setInteger:nLastIdx-1 forKey: kSync_LastDldIdx];
    [userSetting synchronize];
  }
  
}

- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
  //_lblMsg.text = error.description;
  if(error != nil) {
    [self stopSyncProcess:NO];
    
    //last sync exception
    /*if(_nSyncPos > 0 && _nCurSyncHrateId != 0) {
      NSInteger nFrId = _nCurSyncHrateId;
      NSInteger nToId = _nCurSyncHrateId;
      
      if(_sIniSyncHrateId != nil)
        nFrId = _sIniSyncHrateId.integerValue;
      if(_sNewSyncHrateId != nil)
        nToId = _sNewSyncHrateId.integerValue;
      
      AppDelegate* pApp = (AppDelegate*)[[UIApplication sharedApplication] delegate];
      NSInteger nLastIdx = _nSyncPos ;
     
      [pApp updHrateSyncState:nFrId toId:nToId lastIdx:nLastIdx];
      if(!_bSyncGetReqst)
        [pApp updateHrateItemHrateIds:nFrId toId:nToId];
    }*/
    _nLastIdx = _nSyncPos;
    _bSyncError = YES;
    [self updateHrateLastUpdIdx];
    AppDelegate* pApp = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    if(!_bFixHrtData && [pApp isNetWorkConnAvailable])
      [self UrlSessionTimeOut];
    AudioServicesPlaySystemSound(1112);
  }
}

- (void) URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error
{
  [self stopSyncProcess:NO];
  
  //last sync exception
  /*if(_nSyncPos > 0 && _nCurSyncHrateId != 0) {
    NSInteger nFrId = _nCurSyncHrateId;
    NSInteger nToId = _nCurSyncHrateId;
    
    if(_sIniSyncHrateId != nil)
      nFrId = _sIniSyncHrateId.integerValue;
    if(_sNewSyncHrateId != nil)
      nToId = _sNewSyncHrateId.integerValue;
    
    AppDelegate* pApp = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    NSInteger nLastIdx = _nSyncPos ;
    [pApp updHrateSyncState:nFrId toId:nToId lastIdx:nLastIdx];
    if(!_bSyncGetReqst)
      [pApp updateHrateItemHrateIds:nFrId toId:nToId];
  }*/
  _nLastIdx = _nSyncPos;
  [self updateHrateLastUpdIdx];
  
  _bSyncError = YES;
  if(error != nil)
    [self UrlSessionTimeOut];
}

- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
  completionHandler(NSURLSessionResponseAllow);
}

- (BOOL) updateHrateDataIds:(NSString*)sRecv
{
  BOOL bUpd = YES;
  NSString* sFrTo = sRecv;
  NSArray *listItems = [sFrTo componentsSeparatedByString:@" "];
  if(listItems.count > 1)
    sFrTo = listItems[1];
  listItems = [sFrTo componentsSeparatedByString:@"->"];
  if(listItems.count > 1) {
    NSString* sIniHrateId = listItems[0];
    NSString* sNewHrateId = listItems[1];
    //sIniHrateId =[sIniHrateId substringWithRange: NSMakeRange(7, sIniHrateId.length-7)];
    
    AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSInteger nSvrRtnId =  sNewHrateId.integerValue;
    NSInteger nToNewId = nSvrRtnId;
    BOOL bExists = [pApp checkExistsHrateTimeRcd:_nBodyId hrateId:nToNewId time:_dtMeasStart];
    while(bExists) {
      nToNewId++;
      bExists = [pApp checkExistsHrateTimeRcd:_nBodyId hrateId:nToNewId time:_dtMeasStart];
    }
    if(nToNewId != nSvrRtnId) {
      sNewHrateId = [NSString stringWithFormat:@"%ld", (long)nToNewId];
      [pApp updateSvrHrateId:_nBodyId oldId:nSvrRtnId newId:nToNewId];
    }//test
    //[pApp updateSvrHrateId:_nBodyId oldId:23913 newId:24060];
    
    _sIniSyncHrateId = sIniHrateId;
    _sNewSyncHrateId = sNewHrateId;
    _sLastHrateId = _sNewSyncHrateId;
    if([sIniHrateId isEqualToString:sNewHrateId])
       return YES;
    
    /*AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if(_SynsSvrStep == 5) {
      //when end do that
      dispatch_sync(dispatch_get_main_queue(), ^{
        [pApp updateHrateDataHrateId:sIniHrateId toId:sNewHrateId];
        [pApp updateHrateItemHrateIds:sIniHrateId toId:sNewHrateId];
      });
    }
    else if(_SynsSvrStep == 6) {
      dispatch_sync(dispatch_get_main_queue(), ^{
        [pApp updateHrateItemHrateIds:sIniHrateId toId:sNewHrateId];
      });
    }*/
    
    _bUpdHrateId = YES;
  }
  else {
    bUpd = NO;
    //[self stopSyncProcess:NO];
  }
  return bUpd;
}

//- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
  if (data == nil || _bJustUpdActType) {
    //[_actView stopAnimating];
    [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
    _btnSyncTpp.hidden = NO;
    
    NSString* sRecv = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    if([sRecv rangeOfString:NSLocalizedString(@"OK", nil)].location == NSNotFound) {
      AudioServicesPlaySystemSound(1112);
    }
    //else if(!_bSyncGetReqst) {
      /*AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
      [pApp updHrateSyncState:_nCurSyncHrateId toId:_nCurSyncHrateId lastIdx:-1];
      [self reloadHrateData];
      [self showHrtData:_pHrtData];*/
      //_lblMsg.text = [NSString stringWithFormat:@"From  svr: %@", sRecv];
    //}
    return;
  }
  
  NSString* sRecv = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
  sRecv = [sRecv substringWithRange: NSMakeRange(1, sRecv.length-2)];
  
  if(_bFixHrtData) { //fix hrm data
    if([sRecv isEqualToString:NSLocalizedString(@"OK", nil)]) {
      NSString* sHrateId = [NSString stringWithFormat:@"%ld", (long)_nFixHrateId];
      [self sendFixHrtItemnRecd:sHrateId];
      return;
    }
    NSArray *listItems = [sRecv componentsSeparatedByString:@"-"];
    if(listItems == nil || listItems.count != 2) {
      [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
      return;
    }
    NSString* sHrateId =(NSString*)listItems[0];
    NSInteger nHrateId = sHrateId.integerValue;
    if(nHrateId == 0) {
      /*dispatch_async(dispatch_get_main_queue(), ^{
        _lblMsg.text = @"Not miss any data";
      });*/
      //stop animal
      [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
    }
    else if(nHrateId < 0) { //lost data
       [self performSelectorOnMainThread:@selector(startConnActindicator:) withObject:NSLocalizedString(@"Fix HRM data, whole data miss...", nil) waitUntilDone:YES];
      
    }
    else { //last data miss
      _sFixHrtItemLastDt = (NSString*)listItems[1];
      [self performSelectorOnMainThread:@selector(startConnActindicator:) withObject:NSLocalizedString(@"Fix HRM data, last data miss...", nil) waitUntilDone:YES];
      AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
      NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
      [pApp.dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss.SSS"];
      
      NSMutableArray* pAryHrt = [pApp loadHrateInfo:sRecv.integerValue];
      if(pAryHrt.count > 0) {
        H_Rate* pHrt = [pAryHrt objectAtIndex:0];
        NSString* sEndDate = [pApp.dtFmt stringFromDate: pHrt.hEndDate];
        [self sendFixHrtDateEndTime:sHrateId dtEnd:sEndDate];
        //_lblMsg.text = sEndDate;
      }
      
      //NSDate* dt = [NSDate date];
      //NSString* sDt = [pApp.dtFmt stringFromDate:dt];
      
      NSDate* dtLast =  [pApp.dtFmt dateFromString:_sFixHrtItemLastDt];
      _pFixHrtItem = [pApp loadHrateItemLastData:nHrateId dtLast:dtLast];
      if(_pFixHrtItem == nil) {
        [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
        return;
      }
      _nFixHrtItemCnt = (int)_pFixHrtItem.count;
      [self sendFixHrtItemnRecd:sHrateId];
      
      [pApp.dtFmt setDateFormat:sInitDtFmt];
      
    }
    //_bFixHrtData = NO;
    return;
  }
  
  //BOOL bShowProg = YES;
  if(_bSyncGetReqst) {
    //_lblMsg.text = @"Begin get data";
    //NSString* sRecv = [[NSString alloc] initWithData:datFm_sStarta encoding:NSASCIIStringEncoding];
    //uint8_t* hData = [data bytes];
    //[self intHrateItem];
    //nt n = 1;
    if([sRecv isEqualToString:@"Finished"] || [sRecv isEqualToString:NSLocalizedString(@"OK", nil)]) {
      _lblMsg.text = @"Deleted!";
      return;
    }
    else {
      [self storeSyncGetHrateData:data];
      _nSyncCurrentPack++;
    }
  }
  else {
    if(_nSyncTotalPack == 0) {
      return;
    }
    if([sRecv hasPrefix:@"Failed"]) {
      [self setLastSyncPos];
      //[self UrlSessionTimeOut];
      //_nSyncPos--;
      //_nSyncCurrentPack--;
      if([self sendHrateItem]) {
        _nSyncCurrentPack++;
        _nSyncPos++;
      }
      return;
    }
    
    if([sRecv hasPrefix:@"Ready"]) {
      _SynsSvrStep = 4;
      _nSyncPos = 0;
      if([self sendHrateData])
        _nSyncCurrentPack++;
    }
    else if(_sLastHrateId.integerValue <= 0 && [sRecv hasPrefix:@"DataOk"]) {
      _SynsSvrStep = 5;
      [self updateHrateDataIds:sRecv];
      _nSyncPos = 0;
      if([self sendHrateRng])
         _nSyncCurrentPack++;
      //_nSyncPos = 0;
    }
    else if([sRecv hasPrefix:@"RngOk"]) {
      _SynsSvrStep = 6;
      //_nSyncPos = 0;
      /*if(_pHrtData.count > 0 && _nSyncPos == 0) {
        H_Rate* pHrate = [_pHrtData obrefrewshjectAtIndex:0];
        NSInteger nLastIdx = pHrate.nLastUpdIdx.integerValue;
        if(nLastIdx > 0) {
          _nSyncPos = nLastIdx;// + 1;
          _nSyncCurrentPack = _nSyncPos;
        }
      }*/
      if([self sendHrateItem]) {
        _nSyncCurrentPack++;
        _nSyncPos++;
      }
      //bShowProg = NO;
      //[self updateHrateDataIds:sRecv];
    }
    else {
      if([self updateHrateDataIds:sRecv]) {
        if([self sendHrateRng])
          _nSyncCurrentPack++;
        _nSyncPos++;
      }
      if([sRecv hasPrefix:@"Failed"]) {
        if(_nSyncPos > 0) {
          _nSyncPos--;
          _nSyncCurrentPack--;
        }
      }
    }
  }
  
}

- (void) showSyncProgress
{
  if(_nSyncTotalPack > 0) {
    if(_progView != nil && _progView.hidden)
      _progView.hidden = NO;
    if(_actView != nil && !_actView.isAnimating) {
      _lblSyncData.hidden = YES;
      _btnSyncTpp.hidden = YES;
       [_actView performSelectorOnMainThread:@selector(startAnimating) withObject:nil waitUntilDone:NO];
      //[self startActAnimating];
    }
    
    if(_nSyncCurrentPack >= _nSyncTotalPack) {
        _lblMsg.text = NSLocalizedString(@"Wait...", nil);
    }
    else {
      //_lblMsg.text = [NSString stringWithFormat:@"SYNC %ld / %ld with %@...", (long)(_nSyncCurrentPack+1), (long)_nSyncTotalPack, (_bSyncGetReqst?@"Download":@"Upload")];
      _lblMsg.text = [NSString stringWithFormat:(_bSyncGetNotNeed?@"Uploading %ld / %ld":@"Downloading %ld / %ld"), (long)(_nSyncCurrentPack+1), (long)_nSyncTotalPack];
    }
    CGFloat fProg = (CGFloat)(_nSyncCurrentPack+1) / _nSyncTotalPack;
     _progView.progress = fProg;
  }
}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
  if(error != nil) {
    [self stopSyncProcess:NO];
    [self UrlSessionTimeOut];
  }
}

/*- (void) startActAnimating
{
  _lblSyncData.hidden = YES;
  _btnSyncTpp.hidden = YES;
  [_actView startAnimating];
}*/

- (void) updAllRecvHrateLastUpdIdx:(AppDelegate*)pApp
{
  NSInteger nFrId = _nCurSyncHrateId;
  NSInteger nToId = _nCurSyncHrateId;
  
  if(_sIniSyncHrateId != nil)
    nFrId = _sIniSyncHrateId.integerValue;
  if(_sNewSyncHrateId != nil)
    nToId = _sNewSyncHrateId.integerValue;
  
  [pApp updateDldsHreteRecved:_nBodyId];
  if(!_bSyncGetReqst) {
     _nSyncPos = -1;
    [pApp updHrateSyncState:nFrId toId:nToId lastIdx:-1];
    [pApp updateHrateItemHrateIds:nFrId toId:nToId];
    if(nFrId != nToId) {
     [ pApp updHrateSyncState:nToId toId:nToId lastIdx:-1];
      [pApp updateHrateItemHrateIds:nToId toId:nToId];
    }
  }
  else {
    [pApp updHrateSyncState:nFrId toId:nToId lastIdx:-1];
  }
  
  [self reloadHrateData];
  [self showHrtData:_pHrtData];
  
}

- (void) stopSyncProcess:(BOOL)bEnd
{
  if(_bFixHrtData)
    return;
  
  _nLastSyncIdx = 0;
  _bFinishSyncData = bEnd;
  //[_netSession invalidateAndCancel]
  if(bEnd) {
    /*[_netSession getTasksWithCompletionHandler:^(NSArray<NSURLSessionDataTask *> * _Nonnull dataTasks, NSArray<NSURLSessionUploadTask *> * _Nonnull uploadTasks, NSArray<NSURLSessionDownloadTask *> * _Nonnull downloadTasks) {
      //[dataTasks cancel];
    }];*/
    //[_netSession finishTasksAndInvalidate];
    
    AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    pApp.m_nLastHrtId = 0;
    pApp.m_nLastHrate = 0;
    pApp.m_nCurtAvgHrt = 0;
    [_pViewTpp hideHgtBar:NO];
    
    //[_pHrtData removeAllObjects];
    if((_nCurSyncHrateId != 0) || (_sIniSyncHrateId != nil && _sNewSyncHrateId != nil)) {
      /*dispatch_sync(dispatch_get_main_queue(), ^{
        NSInteger nFrId = _nCurSyncHrateId;
        NSInteger nToId = _nCurSyncHrateId;
          
        if(_sIniSyncHrateId != nil)
          nFrId = _sIniSyncHrateId.integerValue;
        if(_sNewSyncHrateId != nil)
          nToId = _sNewSyncHrateId.integerValue;
        
        [pApp updHrateSyncState:nFrId toId:nToId lastIdx:-1];
        if(!_bSyncGetReqst)
          [pApp updateHrateItemHrateIds:nFrId toId:nToId];
        
        [self reloadHrateData];
        [self showHrtData:_pHrtData];
      });*/
      [self performSelectorOnMainThread:@selector(updAllRecvHrateLastUpdIdx:) withObject:pApp waitUntilDone:YES];
    }
    _bMadeRcdMark = YES;
  }
  NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
  [userSetting synchronize];
  [userSetting setInteger:0 forKey:kSync_LastDldIdx];
  
  if(bEnd)
    [self performSelectorOnMainThread:@selector(stopShowSyncCtrld:) withObject:[NSNumber numberWithBool:bEnd] waitUntilDone:NO];
  else
    [self performSelectorOnMainThread:@selector(stopShowSyncCtrld:) withObject:[NSNumber numberWithBool:bEnd] waitUntilDone:NO];
}

-(void) stopShowSyncCtrld:(NSNumber*)bEnd
{ 
  _pHrtData = nil;
  NSString* sMsg = _bSyncGetNotNeed? NSLocalizedString(@"Upload completed!", nil): NSLocalizedString(@"Download completed!", nil);
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  if(![pApp isNetWorkConnAvailable]) {
    NSInteger nLastIdx = _nSyncPos - 1;
    [pApp updHrateSyncLastIdx: _sLastHrateId lastIdx:nLastIdx];
    
    NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
    [userSetting setInteger:_nSyncPos-1 forKey: kSync_LastDldIdx];
    [userSetting synchronize];
    _nLastIdx = _nSyncPos-1;
    
    sMsg = NSLocalizedString(@"No WAN Network CONN.!", nil);
  }
  else if(bEnd) {
    sMsg = _bSyncGetNotNeed? NSLocalizedString(@"Upload already completed!", nil): NSLocalizedString(@"Download already completed!", nil);
  }
  //if(_bSyncGetNotNeed)
    //sMsg = @"HRM Data Already SYNC!";
  
  
  if(_lblMsg.textColor != [UIColor redColor]) {
    
    /*if((_nSyncTotalPack > 0) && (_pHrtData.count > 0) && _pHrtData.count > 0)
      sMsg = @"Sync completed!";
    else if(_nSyncTotalPack == 0) {
      if(_bSyncGetNotNeed)
        sMsg = @"HRM Data Already SYNC!";//@"Not Need SYNC with Download & Upload";
      else
        sMsg = [NSString stringWithFormat:@"Not Need SYNC with %@!", _bSyncGetReqst?@"Download":@"Upload"];
    }
    if(_bMadeRcdMark)
      sMsg = @"Sync completed!";*/
  }

  
  _pHrateItem = nil;
  //refresh Hrate Rng data avoid logout crass
  if(_pHrtRng != nil) {
    NSInteger nCount = (NSInteger)_pHrtRng.count;
    if(nCount > 0) {
      for(NSInteger i=0; i<nCount; i++) {
        H_RateRng* pRngDate = [_pHrtRng objectAtIndex:i];
        [pApp refreshCoreDataItems:pRngDate];
      }
    }
  }
  _pHrtData = [NSMutableArray arrayWithArray:[pApp loadHrateData:_nBodyId from:nil to:nil sort:NO last:NO syncDld:NO]];
  
  // computations 
  [_actView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
  _btnSyncTpp.hidden = NO;
  if(_progView != nil)
    _progView.hidden = YES;
  
  if(!_bSyncSvrError && _lblMsg.textColor != [UIColor redColor])
    _lblMsg.text = sMsg;
  
  if(_bSyncGetNotNeed)
    AudioServicesPlaySystemSound(1109);
  else if(!bEnd.boolValue)
    AudioServicesPlaySystemSound(1112);
  else
    AudioServicesPlaySystemSound(1109);
}

- (BOOL) sendHrateData
{
  if(_bSyncError)
    return NO;
  
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];

  NSMutableArray* mutDate = _pHrtData;
  NSInteger nUpper = mutDate.count - 1;
  if(_nSyncPos > nUpper || nUpper < 0) {
    _nSyncPos = 0;
    _bSyncGetNotNeed = YES;
    [self stopSyncProcess:NO];
    return NO;
  }
    
  H_Rate* hrData = (H_Rate*)[mutDate objectAtIndex:_nSyncPos];
  if(hrData == nil)
    return NO;
  
  /*(if(hrData.hRateId.integerValue > 0) {
    _nSyncPos++;
    return;
  }*/
  
  BOOL bEnd =  _nSyncPos > 0 && _nSyncPos == nUpper;
  NSString* sHrateId = hrData.hRateId.stringValue;
  _sLastHrateId = sHrateId;
  
  if(sHrateId.integerValue < 0 && ![sHrateId isEqualToString:_sLastHrateId]) {
    _sIniSyncHrateId = nil;
    _sNewSyncHrateId = nil;
    _bUpdHrateId = NO;
  }
  NSDate* dtStart = hrData.hEnterDate;
  NSDate* dtEnd = hrData.hEndDate;
  if(dtEnd == nil)
    dtEnd = dtStart;
  NSString* sActType = hrData.actType.stringValue;
  
 
  NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
  [pApp.dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss.SSS"];
  NSString* sMemory = [hrData.bMemory boolValue]? @"true":@"false";
    
  NSDictionary *measData = @{
    @"BodyId" : [NSString stringWithFormat:@"%ld", (long)_nBodyId],
    @"m_nHrateId" : sHrateId,
    @"m_sStart" : [pApp.dtFmt stringFromDate:dtStart],
    @"m_sEnd" : [pApp.dtFmt stringFromDate:dtEnd],
    @"m_nRateIdx" : @"-1", /*bEnd?@"0": @"-1",*/
    @"_bMemory" : sMemory,
    @"_nActType" : sActType,
    @"hType" : @"1"
  };
  
  [pApp.dtFmt setDateFormat:sInitDtFmt];
  
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
  //[NSURLConnection connectionWithRequest:request delegate:self];
  NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  request.timeoutInterval = 20;
  
  /*NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response;
  if (measData) {
    NSDictionary * dataDictionary = [NSJSONSerialization JSONObjectWithData:measData options:kNilOptions error:nil];
  }
  else{
    NSLog (@"%@", error);
    // do whatever to handle the error;
  }*/
  [task resume];
  
  if(bEnd) {
    _nSyncPos = 0;
    [self sendHrateRng];
  }
  
  if(_sLastHrateId.integerValue > 0)
    _bUpdHrateId = YES;
  return YES;
}

- (void) setLastSyncPos
{
  if(_bSyncGetReqst) {
    NSInteger nLastIdx = 0;
    
    NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
    //[userSetting synchronize];
    NSInteger nIdx = [userSetting integerForKey:kSync_LastSyncIdx];
    if(nIdx < _nLastIdx)
      nIdx = _nLastIdx;
    
    if(nLastIdx < nIdx) {
      nLastIdx = nIdx;
    }
    
    if(_nSyncPos >= nLastIdx)
      return;
    
    if(_nSyncPos < nLastIdx) {
      _nSyncPos = nLastIdx;// + 1;
      _nSyncCurrentPack = _nSyncPos;
    }
  }
  else if(_pHrtData.count > 0) {
    H_Rate* pHrate = [_pHrtData objectAtIndex:0];
    NSInteger nLastIdx = pHrate.nLastUpdIdx.integerValue;
    
    NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
    [userSetting synchronize];
    NSInteger nIdx = [userSetting integerForKey:kSync_LastDldIdx];
    if(nIdx < _nLastIdx)
      nIdx = _nLastIdx;
    
    if(nLastIdx < nIdx) {
      nLastIdx = nIdx;
    }
    
    if(_nSyncPos >= nLastIdx)
      return;
    
    if(nLastIdx > 0 && _nSyncPos < nLastIdx) {
      _nSyncPos = nLastIdx;// + 1;
      _nSyncCurrentPack = _nSyncPos;
    }
    else if(nLastIdx == 0) {
      _nSyncPos = 0;
    }
    else if(nLastIdx < 0) { //is OK
      _nSyncPos = 0;
    }
  }
  else {
    _nSyncPos = 0;
  }
  if(_nSyncPos <= 0) {
    NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
    [userSetting synchronize];
    _nSyncPos = [userSetting integerForKey:kSync_LastDldIdx];
  }
  _nSyncCurrentPack = _nSyncPos;
}

- (BOOL) sendHrateRng
{
  if(_bSyncError)
    return NO;
  
  if(_pHrtRng == nil || _pHrtRng.count == 0) {
    if(_SynsSvrStep == 6) {
      if(_sLastHrateId.integerValue > 0) {
        _nSyncPos = 0;
        [self sendHrateItem];
      }
    }
    else {
      [self setLastSyncPos];
      [self sendHrateItem];
    }
    //_nSyncPos++;
    return NO;
  }
  else {
    _nSyncPos = 0;
  }
  
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSMutableArray* mutDate = _pHrtRng;
  NSInteger nUpper = mutDate.count - 1;
  if(_nSyncPos > nUpper || nUpper < 0) {
    if(_SynsSvrStep == 6) {
      if(_sLastHrateId.integerValue > 0) {
        _nSyncPos = 0;
      }
      //_nSyncPos++;
    }
    return NO;
  }
  
  H_RateRng* hrRng = (H_RateRng*)[mutDate objectAtIndex:0];
  if(hrRng == nil) {
    [self sendHrateItem];
    return NO;
  }
  
  /*if(hrRng.measId.integerValue > 0) {
    _nSyncPos++;
    return;
  }*/
  
  BOOL bEnd = _nSyncPos >= nUpper;
  NSString* sHrateId = (_sNewSyncHrateId==nil)?hrRng.hRateId.stringValue: _sNewSyncHrateId;
  long nMeasId = -1;
  NSDate* dtStart = hrRng.startTime;
  
  
  NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
  [pApp.dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss"];
  
  //test
  float fClaories = 0.0, fDurMin = 0;
  NSInteger nCount = mutDate.count;
  for(NSInteger i=0; i<nCount; i++) {
    H_RateRng* hrRngItem  =  (H_RateRng*)[mutDate objectAtIndex:i];
    float fCalore = hrRngItem.caloriesBurned.floatValue;
    fClaories += fCalore;
    fDurMin += hrRngItem.durMinute.floatValue;
  }

  NSDictionary *measData = @{
                             @"BodyId" : [NSString stringWithFormat:@"%ld", (long)_nBodyId],
                             @"m_nMeasId": [NSString stringWithFormat:@"%ld", nMeasId],
                             @"m_nHrateId": sHrateId,
                             //@"m_nRateIdx" : [NSString stringWithFormat:@"%d", hrRng.rateIdx.shortValue],
                             @"m_nRateIdx" : @"0",
                             //@"m_sRateRng" : hrRng.rateRng,
                             @"m_sRateRng" : @"All",
                             @"m_dCalBurned" : [NSString stringWithFormat:@"%.5f", fClaories],
                             //@"m_dDurMinute" :  [NSString stringWithFormat:@"%.3f", hrRng.durMinute.floatValue],
                             @"m_dDurMinute" :  [NSString stringWithFormat:@"%.4f",fDurMin],
                             @"m_dtRngStart" : [pApp.dtFmt stringFromDate:dtStart],
                             @"m_sDateTxt" : hrRng.sDateTxt,
                             @"m_sMonthTxt": hrRng.sMonthTxt,
                             @"hType" : @"2"
                             };
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
  //[NSURLConnection connectionWithRequest:request delegate:self];
  NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  [task resume];
  
  
  [pApp.dtFmt setDateFormat:sInitDtFmt];
  
  if(bEnd) {
    _nSyncPos = 0;
    [self sendHrateItem];
  }
  else {
    [self setLastSyncPos];
  }
  return YES;
}

-(BOOL) sendHrateItem
{
  if(_bSyncError)
    return NO;
  
  AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  NSMutableArray* mutDate = _pSyncItem;
  NSInteger nUpper = mutDate.count - 1;
  //if(_nLastSyncIdx > 0) {
    //nUpper -= 2;
  //}
  if(_nSyncPos == -1 || _nSyncPos > nUpper || nUpper < 0/* || !_bUpdHrateId*/) {
    //_nSyncPos = 0;
    [self stopSyncProcess:YES];
    return NO;
  }
  
  H_RateItem* hrItem = (H_RateItem*)[mutDate objectAtIndex:_nSyncPos];
  if(hrItem == nil)
    return NO;
  
  BOOL bEnd = _nSyncPos > nUpper;
  //NSString* sHrateId = (_sNewSyncHrateId==nil)?hrItem.hRateId.stringValue: _sNewSyncHrateId;
  NSString* sHrateId = nil;
  if(_sNewSyncHrateId != nil)
    sHrateId = _sNewSyncHrateId;
  else
    sHrateId = _sLastHrateId;
  
  if(sHrateId.integerValue <= 0)
    return NO;
    
  
  NSString* sInitDtFmt = pApp.dtFmt.dateFormat;
  [pApp.dtFmt setDateFormat:@"MM/dd/yyyy HH:mm:ss.SSS"];
  
  NSString* dtMeas = [pApp.dtFmt stringFromDate:hrItem.hRateTime];
  NSDictionary *measData = @{
                             @"BodyId" : [NSString stringWithFormat:@"%ld", (long)_nBodyId],
                             @"m_nItemId": hrItem.hItemId.stringValue,
                             @"m_nHrateId":sHrateId,
                             @"HrateVal" : hrItem.hRateValue.stringValue,
                             @"MeasTime" : dtMeas,
                             @"m_nMeasId" : @"-1", /*bEnd?@"0":@"-1",*/
                             @"hType" : @"3"
                             };
  NSMutableURLRequest *request = [pApp requestWebApiRouter:@"POST" url:@"Msync" data:measData];
  //[NSURLConnection connectionWithRequest:request delegate:self];
 
  NSURLSessionDataTask *task = [_netSession dataTaskWithRequest:request];
  [task resume];
  
  if(_nSyncPos > 0 && sHrateId != nil) {
    [pApp.dtFmt setDateFormat:sInitDtFmt];
    NSInteger nLastIdx = _nSyncPos - 1;
    [pApp updHrateSyncLastIdx: sHrateId lastIdx:nLastIdx];
  }

  
  if(bEnd) {
    //_nSyncPos = 0;
    [self stopSyncProcess:YES];
  }
  else {
    [self performSelectorOnMainThread:@selector(showSyncProgress) withObject:nil waitUntilDone:NO];
  }
  return YES;
}

- (void) stopOptTypeCtrl
{
  if(_optSyncViwe != nil) {
    [_optSyncViwe rmvOptTypeButs];
    _optSyncViwe.optDelegate = nil;
    [_optSyncViwe removeFromSuperview];
    _optSyncViwe = nil;
  }
}

- (void) showSyncOption:(NSInteger)nHrateId idx:(NSInteger)nIdx msg:(NSString*)sMsg type:(short)nType
{
  _bSyncError = NO;
  //_lblMsg.text = sMsg;
  [_ddlHrdList hideDropDownList];
  
  if(_optSyncViwe == nil) {
    CGRect frame = [[UIScreen mainScreen] bounds];
    CGFloat W = frame.size.width;
    CGFloat H = frame.size.height;
    
    CGFloat xPos = W / 10.0;
    CGFloat fWidHgt = W - xPos * 2.0;
    CGFloat yPos = (H - fWidHgt) / 2.0 - 25;
    _optSyncViwe = [[UIOptionView alloc] initWithFrame:CGRectMake(xPos, yPos, fWidHgt, fWidHgt * 2 /3)];
  }
  
  short nTypeIdx = [self getActTypeIdx:nIdx];
  [_optSyncViwe addOptTypeButs:nHrateId type:nTypeIdx info:sMsg show:nType];
  _optSyncViwe.optDelegate = self;
  [self.view addSubview:_optSyncViwe];
}

- (void) onOptTypeChgedOk:(NSInteger)nHrateId type:(short)nTapIdx show:(short)nShow
{
  //_lblMsg.text = [NSString stringWithFormat:@"OK:hrate: %ld : %i", (long)nHrateId, nTapIdx];
  [_optSyncViwe removeFromSuperview];
  _optSyncViwe = nil;
  
  _bSyncGetReqst = NO;
  _nSyncTotalPack = 0;
  _bFixHrtData = NO;
  //upload
  if(nTapIdx < 200) {
    _lblMsg.text = NSLocalizedString(@"Start uploading...", nil);
    AppDelegate *pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSString* sHrateId = [NSString stringWithFormat:@"%ld", (long)nHrateId];
    //if(sHrateId.integerValue > 0)
    [pApp updateHrateDataActType:sHrateId actType:nTapIdx];
    
    //refresh
    H_Rate* pHrate =  [_pHrtData objectAtIndex:_nSelTabItemIdx];
    pHrate.actType = [NSNumber numberWithShort:nTapIdx];
    //upload
    _bSyncGetNotNeed = YES;
    [self syncHrateRecvAct:nHrateId actType:nTapIdx];
    [NSThread sleepForTimeInterval:0.25];
    
    if(nShow == 0) {
      _bJustUpdActType = NO;
      _bSyncSvrError = NO;
      _nCurSyncHrateId = nHrateId;
      
      if(nHrateId > 0) {
        _nSyncPos = pHrate.nLastUpdIdx.integerValue;
        if(_nSyncPos > 1)
          _nSyncPos -= 2;
        else if(_nSyncPos > 0)
          _nSyncPos -= 1;
        else if(_nSyncPos < 0)
          _nSyncPos = 0;
        
        NSUserDefaults *userSetting = [NSUserDefaults standardUserDefaults];
        [userSetting synchronize];
        NSInteger nLastIdx = [userSetting integerForKey:kSync_LastDldIdx];
        if(nLastIdx < _nLastIdx)
          nLastIdx = _nLastIdx;
        
        if(_nSyncPos < nLastIdx) {
          _nSyncPos = nLastIdx;
        }
        _nSyncCurrentPack = _nSyncPos;
      }
      [self showActType:_nSelTabItemIdx];
      [self syncSendHrateData:nHrateId];
      //[self sendHrateData];
    }
    else {
      [self showActType:_nSelTabItemIdx];
      _lblMsg.text = NSLocalizedString(@"Act. Type Updated!", nil);
    }
  }
  else {
    _lblMsg.text = NSLocalizedString(@"Cancel", nil);
    AudioServicesPlaySystemSound(1112);
  }
}

-(void) bleDevConnected
{
  _lblMsg.text = NSLocalizedString(@"BLE Disconnected!", nil);
  AudioServicesPlaySystemSound(1112);
}

- (void) bleUserClosed
{
  _ncitBleDev.bleDelegate = nil;
  AppDelegate* pApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  _lblMsg.text = (pApp.m_bSupportBle)? NSLocalizedString(@"BLE Disconnected!", nil): NSLocalizedString(@"BLE Closed, Session Ended", nil);
  
  
  //if(!_bSyncGetReqst) {
    //[pApp updHrateStartEndTime:_hRate startTime: nil endTime:[NSDate date]; toSvr:YES];
    //[self storeRateRngData:YES];
    //pApp.m_nHrateId = 0;
  //}
  AudioServicesPlaySystemSound(1112);
}
@end
